diff --git a/.gitignore b/.gitignore
index 08f570ad06..693a35c176 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,4 @@ spring-call-getters-using-reflection/.mvn/wrapper/maven-wrapper.properties
spring-check-if-a-property-is-null/.mvn/wrapper/maven-wrapper.properties
*.springBeans
+20171220-JMeter.csv
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java
new file mode 100644
index 0000000000..b646c686b2
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java
@@ -0,0 +1,47 @@
+package com.baeldung.algorithms.multiswarm;
+
+/**
+ * Constants used by the Multi-swarm optimization algorithms.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Constants {
+
+ /**
+ * The inertia factor encourages a particle to continue moving in its
+ * current direction.
+ */
+ public static final double INERTIA_FACTOR = 0.729;
+
+ /**
+ * The cognitive weight encourages a particle to move toward its historical
+ * best-known position.
+ */
+ public static final double COGNITIVE_WEIGHT = 1.49445;
+
+ /**
+ * The social weight encourages a particle to move toward the best-known
+ * position found by any of the particle’s swarm-mates.
+ */
+ public static final double SOCIAL_WEIGHT = 1.49445;
+
+ /**
+ * The global weight encourages a particle to move toward the best-known
+ * position found by any particle in any swarm.
+ */
+ public static final double GLOBAL_WEIGHT = 0.3645;
+
+ /**
+ * Upper bound for the random generation. We use it to reduce the
+ * computation time since we can rawly estimate it.
+ */
+ public static final int PARTICLE_UPPER_BOUND = 10000000;
+
+ /**
+ * Private constructor for utility class.
+ */
+ private Constants() {
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java
new file mode 100644
index 0000000000..2d86ec8d94
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java
@@ -0,0 +1,21 @@
+package com.baeldung.algorithms.multiswarm;
+
+/**
+ * Interface for a fitness function, used to decouple the main algorithm logic
+ * from the specific problem solution.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public interface FitnessFunction {
+
+ /**
+ * Returns the fitness of a particle given its position.
+ *
+ * @param particlePosition
+ * the position of the particle
+ * @return the fitness of the particle
+ */
+ public double getFitness(long[] particlePosition);
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java
new file mode 100644
index 0000000000..ef60726278
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java
@@ -0,0 +1,227 @@
+package com.baeldung.algorithms.multiswarm;
+
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Represents a collection of {@link Swarm}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Multiswarm {
+
+ /**
+ * The swarms managed by this multiswarm.
+ */
+ private Swarm[] swarms;
+
+ /**
+ * The best position found within all the {@link #swarms}.
+ */
+ private long[] bestPosition;
+
+ /**
+ * The best fitness score found within all the {@link #swarms}.
+ */
+ private double bestFitness = Double.NEGATIVE_INFINITY;
+
+ /**
+ * A random generator.
+ */
+ private Random random = new Random();
+
+ /**
+ * The fitness function used to determine how good is a particle.
+ */
+ private FitnessFunction fitnessFunction;
+
+ /**
+ * Instantiates a new Multiswarm.
+ *
+ * @param numSwarms
+ * the number of {@link #swarms}
+ * @param particlesPerSwarm
+ * the number of particle for each {@link #swarms}
+ * @param fitnessFunction
+ * the {@link #fitnessFunction}
+ */
+ public Multiswarm(int numSwarms, int particlesPerSwarm, FitnessFunction fitnessFunction) {
+ this.fitnessFunction = fitnessFunction;
+ this.swarms = new Swarm[numSwarms];
+ for (int i = 0; i < numSwarms; i++) {
+ swarms[i] = new Swarm(particlesPerSwarm);
+ }
+ }
+
+ /**
+ * Main loop of the algorithm. Iterates all particles of all
+ * {@link #swarms}. For each particle, computes the new fitness and checks
+ * if a new best position has been found among itself, the swarm and all the
+ * swarms and finally updates the particle position and speed.
+ */
+ public void mainLoop() {
+ for (Swarm swarm : swarms) {
+ for (Particle particle : swarm.getParticles()) {
+
+ long[] particleOldPosition = particle.getPosition().clone();
+
+ // Calculate the particle fitness.
+ particle.setFitness(fitnessFunction.getFitness(particleOldPosition));
+
+ // Check if a new best position has been found for the particle
+ // itself, within the swarm and the multiswarm.
+ if (particle.getFitness() > particle.getBestFitness()) {
+ particle.setBestFitness(particle.getFitness());
+ particle.setBestPosition(particleOldPosition);
+
+ if (particle.getFitness() > swarm.getBestFitness()) {
+ swarm.setBestFitness(particle.getFitness());
+ swarm.setBestPosition(particleOldPosition);
+
+ if (swarm.getBestFitness() > bestFitness) {
+ bestFitness = swarm.getBestFitness();
+ bestPosition = swarm.getBestPosition().clone();
+ }
+
+ }
+ }
+
+ // Updates the particle position by adding the speed to the
+ // actual position.
+ long[] position = particle.getPosition();
+ long[] speed = particle.getSpeed();
+
+ position[0] += speed[0];
+ position[1] += speed[1];
+
+ // Updates the particle speed.
+ speed[0] = getNewParticleSpeedForIndex(particle, swarm, 0);
+ speed[1] = getNewParticleSpeedForIndex(particle, swarm, 1);
+ }
+ }
+ }
+
+ /**
+ * Computes a new speed for a given particle of a given swarm on a given
+ * axis. The new speed is computed using the formula:
+ *
+ *
+ *
+ * @param particle
+ * the particle whose new speed needs to be computed
+ * @param swarm
+ * the swarm which contains the particle
+ * @param index
+ * the index of the particle axis whose speeds needs to be
+ * computed
+ * @return the new speed of the particle passed on the given axis
+ */
+ private int getNewParticleSpeedForIndex(Particle particle, Swarm swarm, int index) {
+ return (int) ((Constants.INERTIA_FACTOR * particle.getSpeed()[index])
+ + (randomizePercentage(Constants.COGNITIVE_WEIGHT)
+ * (particle.getBestPosition()[index] - particle.getPosition()[index]))
+ + (randomizePercentage(Constants.SOCIAL_WEIGHT)
+ * (swarm.getBestPosition()[index] - particle.getPosition()[index]))
+ + (randomizePercentage(Constants.GLOBAL_WEIGHT)
+ * (bestPosition[index] - particle.getPosition()[index])));
+ }
+
+ /**
+ * Returns a random number between 0 and the value passed as argument.
+ *
+ * @param value
+ * the value to randomize
+ * @return a random value between 0 and the one passed as argument
+ */
+ private double randomizePercentage(double value) {
+ return random.nextDouble() * value;
+ }
+
+ /**
+ * Gets the {@link #bestPosition}.
+ *
+ * @return the {@link #bestPosition}
+ */
+ public long[] getBestPosition() {
+ return bestPosition;
+ }
+
+ /**
+ * Gets the {@link #bestFitness}.
+ *
+ * @return the {@link #bestFitness}
+ */
+ public double getBestFitness() {
+ return bestFitness;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(bestFitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(bestPosition);
+ result = prime * result + ((fitnessFunction == null) ? 0 : fitnessFunction.hashCode());
+ result = prime * result + ((random == null) ? 0 : random.hashCode());
+ result = prime * result + Arrays.hashCode(swarms);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Multiswarm other = (Multiswarm) obj;
+ if (Double.doubleToLongBits(bestFitness) != Double.doubleToLongBits(other.bestFitness))
+ return false;
+ if (!Arrays.equals(bestPosition, other.bestPosition))
+ return false;
+ if (fitnessFunction == null) {
+ if (other.fitnessFunction != null)
+ return false;
+ } else if (!fitnessFunction.equals(other.fitnessFunction))
+ return false;
+ if (random == null) {
+ if (other.random != null)
+ return false;
+ } else if (!random.equals(other.random))
+ return false;
+ if (!Arrays.equals(swarms, other.swarms))
+ return false;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Multiswarm [swarms=" + Arrays.toString(swarms) + ", bestPosition=" + Arrays.toString(bestPosition)
+ + ", bestFitness=" + bestFitness + ", random=" + random + ", fitnessFunction=" + fitnessFunction + "]";
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java
new file mode 100644
index 0000000000..5930a94267
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java
@@ -0,0 +1,204 @@
+package com.baeldung.algorithms.multiswarm;
+
+import java.util.Arrays;
+
+/**
+ * Represents a particle, the basic component of a {@link Swarm}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Particle {
+
+ /**
+ * The current position of this particle.
+ */
+ private long[] position;
+
+ /**
+ * The speed of this particle.
+ */
+ private long[] speed;
+
+ /**
+ * The fitness of this particle for the current position.
+ */
+ private double fitness;
+
+ /**
+ * The best position found by this particle.
+ */
+ private long[] bestPosition;
+
+ /**
+ * The best fitness found by this particle.
+ */
+ private double bestFitness = Double.NEGATIVE_INFINITY;
+
+ /**
+ * Instantiates a new Particle.
+ *
+ * @param initialPosition
+ * the initial {@link #position}
+ * @param initialSpeed
+ * the initial {@link #speed}
+ */
+ public Particle(long[] initialPosition, long[] initialSpeed) {
+ this.position = initialPosition;
+ this.speed = initialSpeed;
+ }
+
+ /**
+ * Gets the {@link #position}.
+ *
+ * @return the {@link #position}
+ */
+ public long[] getPosition() {
+ return position;
+ }
+
+ /**
+ * Gets the {@link #speed}.
+ *
+ * @return the {@link #speed}
+ */
+ public long[] getSpeed() {
+ return speed;
+ }
+
+ /**
+ * Gets the {@link #fitness}.
+ *
+ * @return the {@link #fitness}
+ */
+ public double getFitness() {
+ return fitness;
+ }
+
+ /**
+ * Gets the {@link #bestPosition}.
+ *
+ * @return the {@link #bestPosition}
+ */
+ public long[] getBestPosition() {
+ return bestPosition;
+ }
+
+ /**
+ * Gets the {@link #bestFitness}.
+ *
+ * @return the {@link #bestFitness}
+ */
+ public double getBestFitness() {
+ return bestFitness;
+ }
+
+ /**
+ * Sets the {@link #position}.
+ *
+ * @param position
+ * the new {@link #position}
+ */
+ public void setPosition(long[] position) {
+ this.position = position;
+ }
+
+ /**
+ * Sets the {@link #speed}.
+ *
+ * @param speed
+ * the new {@link #speed}
+ */
+ public void setSpeed(long[] speed) {
+ this.speed = speed;
+ }
+
+ /**
+ * Sets the {@link #fitness}.
+ *
+ * @param fitness
+ * the new {@link #fitness}
+ */
+ public void setFitness(double fitness) {
+ this.fitness = fitness;
+ }
+
+ /**
+ * Sets the {@link #bestPosition}.
+ *
+ * @param bestPosition
+ * the new {@link #bestPosition}
+ */
+ public void setBestPosition(long[] bestPosition) {
+ this.bestPosition = bestPosition;
+ }
+
+ /**
+ * Sets the {@link #bestFitness}.
+ *
+ * @param bestFitness
+ * the new {@link #bestFitness}
+ */
+ public void setBestFitness(double bestFitness) {
+ this.bestFitness = bestFitness;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(bestFitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(bestPosition);
+ temp = Double.doubleToLongBits(fitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(position);
+ result = prime * result + Arrays.hashCode(speed);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Particle other = (Particle) obj;
+ if (Double.doubleToLongBits(bestFitness) != Double.doubleToLongBits(other.bestFitness))
+ return false;
+ if (!Arrays.equals(bestPosition, other.bestPosition))
+ return false;
+ if (Double.doubleToLongBits(fitness) != Double.doubleToLongBits(other.fitness))
+ return false;
+ if (!Arrays.equals(position, other.position))
+ return false;
+ if (!Arrays.equals(speed, other.speed))
+ return false;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Particle [position=" + Arrays.toString(position) + ", speed=" + Arrays.toString(speed) + ", fitness="
+ + fitness + ", bestPosition=" + Arrays.toString(bestPosition) + ", bestFitness=" + bestFitness + "]";
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java
new file mode 100644
index 0000000000..e6d37bb7e6
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java
@@ -0,0 +1,155 @@
+package com.baeldung.algorithms.multiswarm;
+
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Represents a collection of {@link Particle}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Swarm {
+
+ /**
+ * The particles of this swarm.
+ */
+ private Particle[] particles;
+
+ /**
+ * The best position found within the particles of this swarm.
+ */
+ private long[] bestPosition;
+
+ /**
+ * The best fitness score found within the particles of this swarm.
+ */
+ private double bestFitness = Double.NEGATIVE_INFINITY;
+
+ /**
+ * A random generator.
+ */
+ private Random random = new Random();
+
+ /**
+ * Instantiates a new Swarm.
+ *
+ * @param numParticles
+ * the number of particles of the swarm
+ */
+ public Swarm(int numParticles) {
+ particles = new Particle[numParticles];
+ for (int i = 0; i < numParticles; i++) {
+ long[] initialParticlePosition = { random.nextInt(Constants.PARTICLE_UPPER_BOUND),
+ random.nextInt(Constants.PARTICLE_UPPER_BOUND) };
+ long[] initialParticleSpeed = { random.nextInt(Constants.PARTICLE_UPPER_BOUND),
+ random.nextInt(Constants.PARTICLE_UPPER_BOUND) };
+ particles[i] = new Particle(initialParticlePosition, initialParticleSpeed);
+ }
+ }
+
+ /**
+ * Gets the {@link #particles}.
+ *
+ * @return the {@link #particles}
+ */
+ public Particle[] getParticles() {
+ return particles;
+ }
+
+ /**
+ * Gets the {@link #bestPosition}.
+ *
+ * @return the {@link #bestPosition}
+ */
+ public long[] getBestPosition() {
+ return bestPosition;
+ }
+
+ /**
+ * Gets the {@link #bestFitness}.
+ *
+ * @return the {@link #bestFitness}
+ */
+ public double getBestFitness() {
+ return bestFitness;
+ }
+
+ /**
+ * Sets the {@link #bestPosition}.
+ *
+ * @param bestPosition
+ * the new {@link #bestPosition}
+ */
+ public void setBestPosition(long[] bestPosition) {
+ this.bestPosition = bestPosition;
+ }
+
+ /**
+ * Sets the {@link #bestFitness}.
+ *
+ * @param bestFitness
+ * the new {@link #bestFitness}
+ */
+ public void setBestFitness(double bestFitness) {
+ this.bestFitness = bestFitness;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(bestFitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(bestPosition);
+ result = prime * result + Arrays.hashCode(particles);
+ result = prime * result + ((random == null) ? 0 : random.hashCode());
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Swarm other = (Swarm) obj;
+ if (Double.doubleToLongBits(bestFitness) != Double.doubleToLongBits(other.bestFitness))
+ return false;
+ if (!Arrays.equals(bestPosition, other.bestPosition))
+ return false;
+ if (!Arrays.equals(particles, other.particles))
+ return false;
+ if (random == null) {
+ if (other.random != null)
+ return false;
+ } else if (!random.equals(other.random))
+ return false;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Swarm [particles=" + Arrays.toString(particles) + ", bestPosition=" + Arrays.toString(bestPosition)
+ + ", bestFitness=" + bestFitness + ", random=" + random + "]";
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java
index ff426cbe68..4b37558aab 100644
--- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java
@@ -40,15 +40,15 @@ public class BacktrackingAlgorithm {
}
private boolean solve(int[][] board) {
- for (int r = BOARD_START_INDEX; r < BOARD_SIZE; r++) {
- for (int c = BOARD_START_INDEX; c < BOARD_SIZE; c++) {
- if (board[r][c] == NO_VALUE) {
+ for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) {
+ for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) {
+ if (board[row][column] == NO_VALUE) {
for (int k = MIN_VALUE; k <= MAX_VALUE; k++) {
- board[r][c] = k;
- if (isValid(board, r, c) && solve(board)) {
+ board[row][column] = k;
+ if (isValid(board, row, column) && solve(board)) {
return true;
}
- board[r][c] = NO_VALUE;
+ board[row][column] = NO_VALUE;
}
return false;
}
@@ -57,44 +57,44 @@ public class BacktrackingAlgorithm {
return true;
}
- private boolean isValid(int[][] board, int r, int c) {
- return rowConstraint(board, r) &&
- columnConstraint(board, c) &&
- subsectionConstraint(board, r, c);
+ private boolean isValid(int[][] board, int row, int column) {
+ return rowConstraint(board, row) &&
+ columnConstraint(board, column) &&
+ subsectionConstraint(board, row, column);
}
- private boolean subsectionConstraint(int[][] board, int r, int c) {
+ private boolean subsectionConstraint(int[][] board, int row, int column) {
boolean[] constraint = new boolean[BOARD_SIZE];
- int subsectionRowStart = (r / SUBSECTION_SIZE) * SUBSECTION_SIZE;
+ int subsectionRowStart = (row / SUBSECTION_SIZE) * SUBSECTION_SIZE;
int subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE;
- int subsectionColumnStart = (c / SUBSECTION_SIZE) * SUBSECTION_SIZE;
+ int subsectionColumnStart = (column / SUBSECTION_SIZE) * SUBSECTION_SIZE;
int subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE;
- for (int i = subsectionRowStart; i < subsectionRowEnd; i++) {
- for (int j = subsectionColumnStart; j < subsectionColumnEnd; j++) {
- if (!checkConstraint(board, i, constraint, j)) return false;
+ for (int r = subsectionRowStart; r < subsectionRowEnd; r++) {
+ for (int c = subsectionColumnStart; c < subsectionColumnEnd; c++) {
+ if (!checkConstraint(board, r, constraint, c)) return false;
}
}
return true;
}
- private boolean columnConstraint(int[][] board, int c) {
+ private boolean columnConstraint(int[][] board, int column) {
boolean[] constraint = new boolean[BOARD_SIZE];
return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
- .allMatch(i -> checkConstraint(board, i, constraint, c));
+ .allMatch(row -> checkConstraint(board, row, constraint, column));
}
- private boolean rowConstraint(int[][] board, int r) {
+ private boolean rowConstraint(int[][] board, int row) {
boolean[] constraint = new boolean[BOARD_SIZE];
return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
- .allMatch(i -> checkConstraint(board, r, constraint, i));
+ .allMatch(column -> checkConstraint(board, row, constraint, column));
}
- private boolean checkConstraint(int[][] board, int r, boolean[] constraint, int c) {
- if (board[r][c] != NO_VALUE) {
- if (!constraint[board[r][c] - 1]) {
- constraint[board[r][c] - 1] = true;
+ private boolean checkConstraint(int[][] board, int row, boolean[] constraint, int column) {
+ if (board[row][column] != NO_VALUE) {
+ if (!constraint[board[row][column] - 1]) {
+ constraint[board[row][column] - 1] = true;
} else {
return false;
}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java
index 76b686afa6..df02ff3d11 100644
--- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java
@@ -34,8 +34,8 @@ public class DancingLinksAlgorithm {
dlx.runSolver();
}
- private int getIndex(int row, int col, int num) {
- return (row - 1) * BOARD_SIZE * BOARD_SIZE + (col - 1) * BOARD_SIZE + (num - 1);
+ private int getIndex(int row, int column, int num) {
+ return (row - 1) * BOARD_SIZE * BOARD_SIZE + (column - 1) * BOARD_SIZE + (num - 1);
}
private boolean[][] createExactCoverBoard() {
@@ -51,12 +51,12 @@ public class DancingLinksAlgorithm {
}
private int checkSubsectionConstraint(boolean[][] coverBoard, int hBase) {
- for (int br = COVER_START_INDEX; br <= BOARD_SIZE; br += SUBSECTION_SIZE) {
- for (int bc = COVER_START_INDEX; bc <= BOARD_SIZE; bc += SUBSECTION_SIZE) {
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row += SUBSECTION_SIZE) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column += SUBSECTION_SIZE) {
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
- for (int rDelta = 0; rDelta < SUBSECTION_SIZE; rDelta++) {
- for (int cDelta = 0; cDelta < SUBSECTION_SIZE; cDelta++) {
- int index = getIndex(br + rDelta, bc + cDelta, n);
+ for (int rowDelta = 0; rowDelta < SUBSECTION_SIZE; rowDelta++) {
+ for (int columnDelta = 0; columnDelta < SUBSECTION_SIZE; columnDelta++) {
+ int index = getIndex(row + rowDelta, column + columnDelta, n);
coverBoard[index][hBase] = true;
}
}
@@ -67,10 +67,10 @@ public class DancingLinksAlgorithm {
}
private int checkColumnConstraint(boolean[][] coverBoard, int hBase) {
- for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) {
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
- for (int r1 = COVER_START_INDEX; r1 <= BOARD_SIZE; r1++) {
- int index = getIndex(r1, c, n);
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
+ int index = getIndex(row, column, n);
coverBoard[index][hBase] = true;
}
}
@@ -79,10 +79,10 @@ public class DancingLinksAlgorithm {
}
private int checkRowConstraint(boolean[][] coverBoard, int hBase) {
- for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) {
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
- for (int c1 = COVER_START_INDEX; c1 <= BOARD_SIZE; c1++) {
- int index = getIndex(r, c1, n);
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) {
+ int index = getIndex(row, column, n);
coverBoard[index][hBase] = true;
}
}
@@ -91,10 +91,10 @@ public class DancingLinksAlgorithm {
}
private int checkCellConstraint(boolean[][] coverBoard, int hBase) {
- for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) {
- for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++, hBase++) {
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++, hBase++) {
for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++) {
- int index = getIndex(r, c, n);
+ int index = getIndex(row, column, n);
coverBoard[index][hBase] = true;
}
}
@@ -104,13 +104,13 @@ public class DancingLinksAlgorithm {
private boolean[][] initializeExactCoverBoard(int[][] board) {
boolean[][] coverBoard = createExactCoverBoard();
- for (int i = COVER_START_INDEX; i <= BOARD_SIZE; i++) {
- for (int j = COVER_START_INDEX; j <= BOARD_SIZE; j++) {
- int n = board[i - 1][j - 1];
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) {
+ int n = board[row - 1][column - 1];
if (n != NO_VALUE) {
for (int num = MIN_VALUE; num <= MAX_VALUE; num++) {
if (num != n) {
- Arrays.fill(coverBoard[getIndex(i, j, num)], false);
+ Arrays.fill(coverBoard[getIndex(row, column, num)], false);
}
}
}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java
index b494eba9ef..2422ff0dff 100644
--- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java
@@ -4,21 +4,21 @@ class DancingNode {
DancingNode L, R, U, D;
ColumnNode C;
- DancingNode hookDown(DancingNode n1) {
- assert (this.C == n1.C);
- n1.D = this.D;
- n1.D.U = n1;
- n1.U = this;
- this.D = n1;
- return n1;
+ DancingNode hookDown(DancingNode node) {
+ assert (this.C == node.C);
+ node.D = this.D;
+ node.D.U = node;
+ node.U = this;
+ this.D = node;
+ return node;
}
- DancingNode hookRight(DancingNode n1) {
- n1.R = this.R;
- n1.R.L = n1;
- n1.L = this;
- this.R = n1;
- return n1;
+ DancingNode hookRight(DancingNode node) {
+ node.R = this.R;
+ node.R.L = node;
+ node.L = this;
+ this.R = node;
+ return node;
}
void unlinkLR() {
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java
new file mode 100644
index 0000000000..726d4c135d
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java
@@ -0,0 +1,52 @@
+package com.baeldung.algorithms.multiswarm;
+
+/**
+ * Specific fitness function implementation to solve the League of Legends
+ * problem. This is the problem statement:
+ *
+ * In League of Legends, a player's Effective Health when defending against
+ * physical damage is given by E=H(100+A)/100, where H is health and A is armor.
+ * Health costs 2.5 gold per unit, and Armor costs 18 gold per unit. You have
+ * 3600 gold, and you need to optimize the effectiveness E of your health and
+ * armor to survive as long as possible against the enemy team's attacks. How
+ * much of each should you buy?
+ *
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class LolFitnessFunction implements FitnessFunction {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.baeldung.algorithms.multiswarm.FitnessFunction#getFitness(long[])
+ */
+ @Override
+ public double getFitness(long[] particlePosition) {
+
+ long health = particlePosition[0];
+ long armor = particlePosition[1];
+
+ // No negatives values accepted.
+ if (health < 0 && armor < 0) {
+ return -(health * armor);
+ } else if (health < 0) {
+ return health;
+ } else if (armor < 0) {
+ return armor;
+ }
+
+ // Checks if the solution is actually feasible provided our gold.
+ double cost = (health * 2.5) + (armor * 18);
+ if (cost > 3600) {
+ return 3600 - cost;
+ } else {
+ // Check how good is the solution.
+ long fitness = (health * (100 + armor)) / 100;
+ return fitness;
+ }
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java
new file mode 100644
index 0000000000..3455cd3932
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.algorithms.multiswarm;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.baeldung.algorithms.support.MayFailRule;
+
+/**
+ * Test for {@link Multiswarm}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class MultiswarmUnitTest {
+
+ /**
+ * Rule for handling expected failures. We use this since this test may
+ * actually fail due to bad luck in the random generation.
+ */
+ @Rule
+ public MayFailRule mayFailRule = new MayFailRule();
+
+ /**
+ * Tests the multiswarm algorithm with a generic problem. The problem is the
+ * following:
+ *
+ * In League of Legends, a player's Effective Health when defending against
+ * physical damage is given by E=H(100+A)/100, where H is health and A is
+ * armor. Health costs 2.5 gold per unit, and Armor costs 18 gold per unit.
+ * You have 3600 gold, and you need to optimize the effectiveness E of your
+ * health and armor to survive as long as possible against the enemy team's
+ * attacks. How much of each should you buy?
+ *
+ * The solution is H = 1080, A = 50 for a total fitness of 1620. Tested with
+ * 50 swarms each with 1000 particles.
+ */
+ @Test
+ public void givenMultiswarm_whenThousandIteration_thenSolutionFound() {
+ Multiswarm multiswarm = new Multiswarm(50, 1000, new LolFitnessFunction());
+
+ // Iterates 1000 times through the main loop and prints the result.
+ for (int i = 0; i < 1000; i++) {
+ multiswarm.mainLoop();
+ }
+
+ System.out.println("Best fitness found: " + multiswarm.getBestFitness() + "[" + multiswarm.getBestPosition()[0]
+ + "," + multiswarm.getBestPosition()[1] + "]");
+ Assert.assertEquals(1080, multiswarm.getBestPosition()[0]);
+ Assert.assertEquals(50, multiswarm.getBestPosition()[1]);
+ Assert.assertEquals(1620, (int) multiswarm.getBestFitness());
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/support/MayFailRule.java b/algorithms/src/test/java/com/baeldung/algorithms/support/MayFailRule.java
new file mode 100644
index 0000000000..91df78ce4a
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/support/MayFailRule.java
@@ -0,0 +1,38 @@
+package com.baeldung.algorithms.support;
+
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * JUnit custom rule for managing tests that may fail due to heuristics or
+ * randomness. In order to use this, just instantiate this object as a public
+ * field inside the test class and annotate it with {@link Rule}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class MayFailRule implements TestRule {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.junit.rules.TestRule#apply(org.junit.runners.model.Statement,
+ * org.junit.runner.Description)
+ */
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ } catch (Throwable e) {
+ // Ignore the exception since we expect this.
+ }
+ }
+ };
+ }
+
+}
diff --git a/apache-zookeeper/pom.xml b/apache-zookeeper/pom.xml
new file mode 100644
index 0000000000..6d49d74ade
--- /dev/null
+++ b/apache-zookeeper/pom.xml
@@ -0,0 +1,30 @@
+
+ 4.0.0
+ com.baeldung
+ apache-zookeeper
+ 0.0.1-SNAPSHOT
+ jar
+
+
+
+ org.apache.zookeeper
+ zookeeper
+ 3.3.2
+
+
+ com.sun.jmx
+ jmxri
+
+
+ com.sun.jdmk
+ jmxtools
+
+
+ javax.jms
+ jms
+
+
+
+
+
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java
new file mode 100644
index 0000000000..0678250d57
--- /dev/null
+++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java
@@ -0,0 +1,33 @@
+package com.baeldung.zookeeper.connection;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooKeeper;
+
+public class ZKConnection {
+ private ZooKeeper zoo;
+ final CountDownLatch connectionLatch = new CountDownLatch(1);
+
+ public ZKConnection() {
+ }
+
+ public ZooKeeper connect(String host) throws IOException, InterruptedException {
+ zoo = new ZooKeeper(host, 2000, new Watcher() {
+ public void process(WatchedEvent we) {
+ if (we.getState() == KeeperState.SyncConnected) {
+ connectionLatch.countDown();
+ }
+ }
+ });
+ connectionLatch.await();
+ return zoo;
+ }
+
+ public void close() throws InterruptedException {
+ zoo.close();
+ }
+}
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java
new file mode 100644
index 0000000000..0c0ad52123
--- /dev/null
+++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java
@@ -0,0 +1,35 @@
+package com.baeldung.zookeeper.manager;
+
+import org.apache.zookeeper.KeeperException;
+
+public interface ZKManager {
+ /**
+ * Create a Znode and save some data
+ *
+ * @param path
+ * @param data
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ public void create(String path, byte[] data) throws KeeperException, InterruptedException;
+
+ /**
+ * Get ZNode Data
+ *
+ * @param path
+ * @param boolean watchFlag
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ public Object getZNodeData(String path, boolean watchFlag);
+
+ /**
+ * Update the ZNode Data
+ *
+ * @param path
+ * @param data
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ public void update(String path, byte[] data) throws KeeperException, InterruptedException, KeeperException;
+}
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java
new file mode 100644
index 0000000000..adf76bc0f2
--- /dev/null
+++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java
@@ -0,0 +1,58 @@
+package com.baeldung.zookeeper.manager;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+
+import com.baeldung.zookeeper.connection.ZKConnection;
+
+public class ZKManagerImpl implements ZKManager {
+ private static ZooKeeper zkeeper;
+ private static ZKConnection zkConnection;
+
+ public ZKManagerImpl() {
+ initialize();
+ }
+
+ /** * Initialize connection */
+ private void initialize() {
+ try {
+ zkConnection = new ZKConnection();
+ zkeeper = zkConnection.connect("localhost");
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ public void closeConnection() {
+ try {
+ zkConnection.close();
+ } catch (InterruptedException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ public void create(String path, byte[] data) throws KeeperException, InterruptedException {
+ zkeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ }
+
+ public Object getZNodeData(String path, boolean watchFlag) {
+ try {
+ byte[] b = null;
+ b = zkeeper.getData(path, null, null);
+ String data = new String(b, "UTF-8");
+ System.out.println(data);
+ return data;
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ return null;
+ }
+
+ public void update(String path, byte[] data) throws KeeperException, InterruptedException {
+ int version = zkeeper.exists(path, true)
+ .getVersion();
+ zkeeper.setData(path, data, version);
+ }
+}
diff --git a/checker-plugin/pom.xml b/checker-plugin/pom.xml
new file mode 100644
index 0000000000..bc7a669d4f
--- /dev/null
+++ b/checker-plugin/pom.xml
@@ -0,0 +1,114 @@
+
+ 4.0.0
+ com.baeldung
+ checker-plugin
+ jar
+ 1.0-SNAPSHOT
+ checker-plugin
+ http://maven.apache.org
+
+
+
+
+
+ ${org.checkerframework:jdk8:jar}
+
+
+
+
+
+
+
+
+
+ org.checkerframework
+ checker-qual
+ 2.3.1
+
+
+ org.checkerframework
+ checker
+ 2.3.1
+
+
+ org.checkerframework
+ jdk8
+ 2.3.1
+
+
+
+ org.checkerframework
+ compiler
+ 2.3.1
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+
+
+ properties
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.6.1
+
+ 1.8
+ 1.8
+
+
+
+ 10000
+ 10000
+
+
+
+ org.checkerframework.checker.nullness.NullnessChecker
+ org.checkerframework.checker.interning.InterningChecker
+ org.checkerframework.checker.fenum.FenumChecker
+ org.checkerframework.checker.formatter.FormatterChecker
+ org.checkerframework.checker.regex.RegexChecker
+
+
+ -AprintErrorStack
+
+
+ -Xbootclasspath/p:${annotatedJdk}
+
+
+
+
+
+ -Awarns
+
+
+
+
+
+
+
diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java
new file mode 100644
index 0000000000..f1769cfdea
--- /dev/null
+++ b/checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java
@@ -0,0 +1,42 @@
+package com.baeldung.typechecker;
+
+import org.checkerframework.checker.fenum.qual.Fenum;
+
+//@SuppressWarnings("fenum:assignment.type.incompatible")
+public class FakeNumExample {
+
+ // Here we use some String constants to represents countries.
+ static final @Fenum("country") String ITALY = "IT";
+ static final @Fenum("country") String US = "US";
+ static final @Fenum("country") String UNITED_KINGDOM = "UK";
+
+ // Here we use other String constants to represent planets instead.
+ static final @Fenum("planet") String MARS = "Mars";
+ static final @Fenum("planet") String EARTH = "Earth";
+ static final @Fenum("planet") String VENUS = "Venus";
+
+ // Now we write this method and we want to be sure that
+ // the String parameter has a value of a country, not that is just a String.
+ void greetCountries(@Fenum("country") String country) {
+ System.out.println("Hello " + country);
+ }
+
+ // Similarly we're enforcing here that the provided
+ // parameter is a String that represent a planet.
+ void greetPlanets(@Fenum("planet") String planet) {
+ System.out.println("Hello " + planet);
+ }
+
+ public static void main(String[] args) {
+
+ FakeNumExample obj = new FakeNumExample();
+
+ // This will fail because we pass a planet-String to a method that
+ // accept a country-String.
+ obj.greetCountries(MARS);
+
+ // Here the opposite happens.
+ obj.greetPlanets(US);
+ }
+
+}
diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java
new file mode 100644
index 0000000000..2fa53ff2c2
--- /dev/null
+++ b/checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java
@@ -0,0 +1,23 @@
+package com.baeldung.typechecker;
+
+public class FormatExample {
+
+ public static void main(String[] args) {
+
+ // Just enabling org.checkerframework.checker.formatter.FormatterChecker
+ // we can be sure at compile time that the format strings we pass to format()
+ // are correct. Normally we would have those errors raised just at runtime.
+ // All those formats are in fact wrong.
+
+ String.format("%y", 7); // error: invalid format string
+
+ String.format("%d", "a string"); // error: invalid argument type for %d
+
+ String.format("%d %s", 7); // error: missing argument for %s
+
+ String.format("%d", 7, 3); // warning: unused argument 3
+
+ String.format("{0}", 7); // warning: unused argument 7, because {0} is wrong syntax
+ }
+
+}
diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java
new file mode 100644
index 0000000000..b3072b72ee
--- /dev/null
+++ b/checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java
@@ -0,0 +1,31 @@
+package com.baeldung.typechecker;
+
+import org.checkerframework.checker.nullness.qual.KeyFor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class KeyForExample {
+
+ private final Map config = new HashMap<>();
+
+ KeyForExample() {
+
+ // Here we initialize a map to store
+ // some config data.
+ config.put("url", "http://1.2.3.4");
+ config.put("name", "foobaz");
+ }
+
+ public void dumpPort() {
+
+ // Here, we want to dump the port value stored in the
+ // config, so we declare that this key has to be
+ // present in the config map.
+ // Obviously that will fail because such key is not present
+ // in the map.
+ @KeyFor("config") String key = "port";
+ System.out.println( config.get(key) );
+ }
+
+}
diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java
new file mode 100644
index 0000000000..c4b9c6afe1
--- /dev/null
+++ b/checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java
@@ -0,0 +1,28 @@
+package com.baeldung.typechecker;
+
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
+
+import java.util.Date;
+
+public class MonotonicNotNullExample {
+
+ // The idea is we need this field to be to lazily initialized,
+ // so it starts as null but once it becomes not null
+ // it cannot return null.
+ // In these cases, we can use @MonotonicNonNull
+ @MonotonicNonNull private Date firstCall;
+
+ public Date getFirstCall() {
+ if (firstCall == null) {
+ firstCall = new Date();
+ }
+ return firstCall;
+ }
+
+ public void reset() {
+ // This is reported as error because
+ // we wrongly set the field back to null.
+ firstCall = null;
+ }
+
+}
diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java
new file mode 100644
index 0000000000..c929eea23f
--- /dev/null
+++ b/checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java
@@ -0,0 +1,27 @@
+package com.baeldung.typechecker;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public class NonNullExample {
+
+ // This method's parameter is annotated in order
+ // to tell the pluggable type system that it can never be null.
+ private static int countArgs(@NonNull String[] args) {
+ return args.length;
+ }
+
+ // This method's parameter is annotated in order
+ // to tell the pluggable type system that it may be null.
+ public static void main(@Nullable String[] args) {
+
+ // Here lies a potential error,
+ // because we pass a potential null reference to a method
+ // that does not accept nulls.
+ // The Checker Framework will spot this problem at compile time
+ // instead of runtime.
+ System.out.println(countArgs(args));
+
+ }
+
+}
diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java
new file mode 100644
index 0000000000..9503865214
--- /dev/null
+++ b/checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java
@@ -0,0 +1,18 @@
+package com.baeldung.typechecker;
+
+import org.checkerframework.checker.regex.qual.Regex;
+
+public class RegexExample {
+
+ // For some reason we want to be sure that this regex
+ // contains at least one capturing group.
+ // However, we do an error and we forgot to define such
+ // capturing group in it.
+ @Regex(1) private static String findNumbers = "\\d*";
+
+ public static void main(String[] args) {
+ String message = "My phone number is +3911223344.";
+ message.matches(findNumbers);
+ }
+
+}
diff --git a/core-groovy/README.md b/core-groovy/README.md
new file mode 100644
index 0000000000..5954a8ab7e
--- /dev/null
+++ b/core-groovy/README.md
@@ -0,0 +1,4 @@
+# Groovy
+
+## Relevant articles:
+
diff --git a/core-groovy/build.gradle b/core-groovy/build.gradle
new file mode 100644
index 0000000000..b3f33836da
--- /dev/null
+++ b/core-groovy/build.gradle
@@ -0,0 +1,13 @@
+group 'com.baeldung'
+version '1.0-SNAPSHOT'
+
+apply plugin: 'groovy'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile 'org.codehaus.groovy:groovy-all:2.5.0-alpha-1'
+ testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
+}
diff --git a/core-groovy/pom.xml b/core-groovy/pom.xml
new file mode 100644
index 0000000000..961a4ba125
--- /dev/null
+++ b/core-groovy/pom.xml
@@ -0,0 +1,128 @@
+
+
+ 4.0.0
+
+ core-groovy
+ 1.0-SNAPSHOT
+ jar
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ central
+ http://jcenter.bintray.com
+
+
+
+
+
+ org.codehaus.groovy
+ groovy
+ 2.5.0-alpha-1
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.5.0-alpha-1
+
+
+ org.codehaus.groovy
+ groovy-sql
+ 2.5.0-alpha-1
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.jupiter.version}
+ test
+
+
+ org.junit.platform
+ junit-platform-runner
+ ${junit.platform.version}
+ test
+
+
+ org.hsqldb
+ hsqldb
+ 2.4.0
+ test
+
+
+ org.spockframework
+ spock-core
+ 1.1-groovy-2.4
+ test
+
+
+
+
+
+
+ org.codehaus.gmavenplus
+ gmavenplus-plugin
+ 1.6
+
+
+
+ addSources
+ addTestSources
+ compile
+ compileTests
+
+
+
+
+
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ maven-failsafe-plugin
+ 2.19.1
+
+
+ org.junit.platform
+ junit-platform-surefire-provider
+ ${junit.platform.version}
+
+
+
+
+ junit5
+
+ integration-test
+ verify
+
+
+
+ **/*Test5.java
+
+
+
+
+
+
+
+
+
+ UTF-8
+ 1.1.2
+ 1.1.2
+ 1.1.2
+ 1.1.2
+ 0.15
+ 1.5.0
+
+ 5.0.0
+ 1.0.0
+ 4.12.0
+ 4.12
+
+
+
diff --git a/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy b/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy
new file mode 100644
index 0000000000..84b294f0bd
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy
@@ -0,0 +1,7 @@
+package com.baeldung.json
+
+class Account {
+ String id
+ BigDecimal value
+ Date createdAt
+}
\ No newline at end of file
diff --git a/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
new file mode 100644
index 0000000000..0d7c451972
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
@@ -0,0 +1,36 @@
+package com.baeldung.json
+
+import groovy.json.JsonGenerator
+import groovy.json.JsonOutput
+import groovy.json.JsonParserType
+import groovy.json.JsonSlurper
+
+class JsonParser {
+
+ Account toObject(String json) {
+ JsonSlurper jsonSlurper = new JsonSlurper()
+ jsonSlurper.parseText(json) as Account
+ }
+
+ Account toObjectWithIndexOverlay(String json) {
+ JsonSlurper jsonSlurper = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY)
+ jsonSlurper.parseText(json) as Account
+ }
+
+ String toJson(Account account) {
+ JsonOutput.toJson(account)
+ }
+
+ String toJson(Account account, String dateFormat, String... fieldsToExclude) {
+ JsonGenerator generator = new JsonGenerator.Options()
+ .dateFormat(dateFormat)
+ .excludeFieldsByName(fieldsToExclude)
+ .build()
+ generator.toJson(account)
+ }
+
+ String prettyfy(String json) {
+ JsonOutput.prettyPrint(json)
+ }
+
+}
diff --git a/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy b/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy
new file mode 100644
index 0000000000..ac96a55773
--- /dev/null
+++ b/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy
@@ -0,0 +1,229 @@
+package com.baeldung.groovy.sql
+
+import groovy.sql.GroovyResultSet
+import groovy.sql.GroovyRowResult
+import groovy.sql.Sql
+import groovy.transform.CompileStatic
+import static org.junit.Assert.*
+import org.junit.Test
+
+class SqlTest {
+
+ final Map dbConnParams = [url: 'jdbc:hsqldb:mem:testDB', user: 'sa', password: '', driver: 'org.hsqldb.jdbc.JDBCDriver']
+
+ @Test
+ void whenNewSqlInstance_thenDbIsAccessed() {
+ def sql = Sql.newInstance(dbConnParams)
+ sql.close()
+ sql.close()
+ }
+
+ @Test
+ void whenTableDoesNotExist_thenSelectFails() {
+ try {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.eachRow('select * from PROJECT') {}
+ }
+
+ fail("An exception should have been thrown")
+ } catch (ignored) {
+ //Ok
+ }
+ }
+
+ @Test
+ void whenTableCreated_thenSelectIsPossible() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ def result = sql.execute 'create table PROJECT_1 (id integer not null, name varchar(50), url varchar(100))'
+
+ assertEquals(0, sql.updateCount)
+ assertFalse(result)
+
+ result = sql.execute('select * from PROJECT_1')
+
+ assertTrue(result)
+ }
+ }
+
+ @Test
+ void whenIdentityColumn_thenInsertReturnsNewId() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.execute 'create table PROJECT_2 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ def ids = sql.executeInsert("INSERT INTO PROJECT_2 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
+
+ assertEquals(0, ids[0][0])
+
+ ids = sql.executeInsert("INSERT INTO PROJECT_2 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')")
+
+ assertEquals(1, ids[0][0])
+ }
+ }
+
+ @Test
+ void whenUpdate_thenNumberOfAffectedRows() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.execute 'create table PROJECT_3 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
+ sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')")
+ def count = sql.executeUpdate("UPDATE PROJECT_3 SET URL = 'https://' + URL")
+
+ assertEquals(2, count)
+ }
+ }
+
+ @Test
+ void whenEachRow_thenResultSetHasProperties() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.execute 'create table PROJECT_4 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
+ sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')")
+
+ sql.eachRow("SELECT * FROM PROJECT_4") { GroovyResultSet rs ->
+ assertNotNull(rs.name)
+ assertNotNull(rs.url)
+ assertNotNull(rs[0])
+ assertNotNull(rs[1])
+ assertNotNull(rs[2])
+ assertEquals(rs.name, rs['name'])
+ assertEquals(rs.url, rs['url'])
+ }
+ }
+ }
+
+ @Test
+ void whenPagination_thenSubsetIsReturned() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.execute 'create table PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
+ sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')")
+ def rows = sql.rows('SELECT * FROM PROJECT_5 ORDER BY NAME', 1, 1)
+
+ assertEquals(1, rows.size())
+ assertEquals('REST with Spring', rows[0].name)
+ }
+ }
+
+ @Test
+ void whenParameters_thenReplacement() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.execute 'create table PROJECT_6 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.execute('INSERT INTO PROJECT_6 (NAME, URL) VALUES (?, ?)', 'tutorials', 'github.com/eugenp/tutorials')
+ sql.execute("INSERT INTO PROJECT_6 (NAME, URL) VALUES (:name, :url)", [name: 'REST with Spring', url: 'github.com/eugenp/REST-With-Spring'])
+
+ def rows = sql.rows("SELECT * FROM PROJECT_6 WHERE NAME = 'tutorials'")
+
+ assertEquals(1, rows.size())
+
+ rows = sql.rows("SELECT * FROM PROJECT_6 WHERE NAME = 'REST with Spring'")
+
+ assertEquals(1, rows.size())
+ }
+ }
+
+ @Test
+ void whenParametersInGString_thenReplacement() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.execute 'create table PROJECT_7 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.execute "INSERT INTO PROJECT_7 (NAME, URL) VALUES (${'tutorials'}, ${'github.com/eugenp/tutorials'})"
+ def name = 'REST with Spring'
+ def url = 'github.com/eugenp/REST-With-Spring'
+ sql.execute "INSERT INTO PROJECT_7 (NAME, URL) VALUES (${name}, ${url})"
+
+ def rows = sql.rows("SELECT * FROM PROJECT_7 WHERE NAME = 'tutorials'")
+
+ assertEquals(1, rows.size())
+
+ rows = sql.rows("SELECT * FROM PROJECT_7 WHERE NAME = 'REST with Spring'")
+
+ assertEquals(1, rows.size())
+ }
+ }
+
+ @Test
+ void whenTransactionRollback_thenNoDataInserted() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.withTransaction {
+ sql.execute 'create table PROJECT_8 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
+ sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')")
+ sql.rollback()
+
+ def rows = sql.rows("SELECT * FROM PROJECT_8")
+
+ assertEquals(0, rows.size())
+ }
+ }
+ }
+
+ @Test
+ void whenTransactionRollbackThenCommit_thenOnlyLastInserted() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.withTransaction {
+ sql.execute 'create table PROJECT_9 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
+ sql.rollback()
+ sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')")
+ sql.rollback()
+ sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
+ sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')")
+ }
+
+ def rows = sql.rows("SELECT * FROM PROJECT_9")
+
+ assertEquals(2, rows.size())
+ }
+ }
+
+ @Test
+ void whenException_thenTransactionIsRolledBack() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ try {
+ sql.withTransaction {
+ sql.execute 'create table PROJECT_10 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_10 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
+ throw new Exception('rollback')
+ }
+ } catch (ignored) {}
+
+ def rows = sql.rows("SELECT * FROM PROJECT_10")
+
+ assertEquals(0, rows.size())
+ }
+ }
+
+ @Test
+ void givenCachedConnection_whenException_thenDataIsPersisted() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ try {
+ sql.cacheConnection {
+ sql.execute 'create table PROJECT_11 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_11 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
+ throw new Exception('This does not rollback')
+ }
+ } catch (ignored) {}
+
+ def rows = sql.rows("SELECT * FROM PROJECT_11")
+
+ assertEquals(1, rows.size())
+ }
+ }
+
+ /*@Test
+ void whenModifyResultSet_thenDataIsChanged() {
+ Sql.withInstance(dbConnParams) { Sql sql ->
+ sql.execute 'create table PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
+ sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
+ sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')")
+
+ sql.eachRow("SELECT * FROM PROJECT_5 FOR UPDATE ") { GroovyResultSet rs ->
+ rs['name'] = "The great ${rs.name}!" as String
+ rs.updateRow()
+ }
+
+ sql.eachRow("SELECT * FROM PROJECT_5") { GroovyResultSet rs ->
+ assertTrue(rs.name.startsWith('The great '))
+ }
+ }
+ }*/
+
+}
diff --git a/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
new file mode 100644
index 0000000000..fcd51d58bc
--- /dev/null
+++ b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
@@ -0,0 +1,80 @@
+package com.baeldung.json
+
+import spock.lang.Specification
+
+import java.text.SimpleDateFormat
+
+class JsonParserTest extends Specification {
+
+ JsonParser jsonParser
+
+ void setup () {
+ jsonParser = new JsonParser()
+ }
+
+ def 'Should parse to Account given Json String' () {
+ given:
+ def json = '{"id":"1234","value":15.6}'
+ when:
+ def account = jsonParser.toObject(json)
+ then:
+ account
+ account instanceof Account
+ account.id == '1234'
+ account.value == 15.6
+ }
+
+ def 'Should parse to Account given Json String with date property' () {
+ given:
+ def json = '{"id":"1234","value":15.6,"createdAt":"2018-01-01T00:00:00+0000"}'
+ when:
+ def account = jsonParser.toObjectWithIndexOverlay(json)
+ then:
+ account
+ account instanceof Account
+ account.id == '1234'
+ account.value == 15.6
+ println account.createdAt
+ account.createdAt == Date.parse('yyyy-MM-dd', '2018-01-01')
+ }
+
+ def 'Should parse to Json given an Account object' () {
+ given:
+ Account account = new Account(
+ id: '123',
+ value: 15.6,
+ createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018')
+ )
+ when:
+ def json = jsonParser.toJson(account)
+ then:
+ json
+ json == '{"value":15.6,"createdAt":"2018-01-01T00:00:00+0000","id":"123"}'
+ }
+
+ def 'Should parse to Json given an Account object, a date format and fields to exclude' () {
+ given:
+ Account account = new Account(
+ id: '123',
+ value: 15.6,
+ createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018')
+ )
+ when:
+ def json = jsonParser.toJson(account, 'MM/dd/yyyy', 'value')
+ then:
+ json
+ json == '{"createdAt":"01/01/2018","id":"123"}'
+ }
+
+ def 'Should prettify given a json string' () {
+ given:
+ String json = '{"value":15.6,"createdAt":"01/01/2018","id":"123456"}'
+ when:
+ def jsonPretty = jsonParser.prettyfy(json)
+ then:
+ jsonPretty
+ jsonPretty == '{\n "value": 15.6,\n "createdAt": "01/01/2018",\n "id": "123456"\n}'
+ }
+
+
+}
diff --git a/core-java-8/README.md b/core-java-8/README.md
index 9260e3d447..1b5208961d 100644
--- a/core-java-8/README.md
+++ b/core-java-8/README.md
@@ -40,3 +40,4 @@
- [Efficient Word Frequency Calculator in Java](http://www.baeldung.com/java-word-frequency)
- [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams)
- [Fail-Safe Iterator vs Fail-Fast Iterator](http://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator)
+- [Shuffling Collections In Java](http://www.baeldung.com/java-shuffle-collection)
diff --git a/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java b/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java
new file mode 100644
index 0000000000..d013907c9a
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.shufflingcollections;
+
+import org.junit.Test;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ShufflingCollectionsUnitTest {
+
+ @Test
+ public void whenShufflingList_thenListIsShuffled() {
+ List students = Arrays.asList("Foo", "Bar", "Baz", "Qux");
+
+ System.out.println("List before shuffling:");
+ System.out.println(students);
+
+ Collections.shuffle(students);
+ System.out.println("List after shuffling:");
+ System.out.println(students);
+ }
+
+ @Test
+ public void whenShufflingMapEntries_thenValuesAreShuffled() {
+ Map studentsById = new HashMap<>();
+ studentsById.put(1, "Foo");
+ studentsById.put(2, "Bar");
+ studentsById.put(3, "Baz");
+ studentsById.put(4, "Qux");
+
+ System.out.println("Students before shuffling:");
+ System.out.println(studentsById.values());
+
+ List> shuffledStudentEntries = new ArrayList<>(studentsById.entrySet());
+ Collections.shuffle(shuffledStudentEntries);
+
+ List shuffledStudents = shuffledStudentEntries.stream()
+ .map(Map.Entry::getValue)
+ .collect(Collectors.toList());
+
+ System.out.println("Students after shuffling");
+ System.out.println(shuffledStudents);
+ }
+
+ @Test
+ public void whenShufflingSet_thenElementsAreShuffled() {
+ Set students = new HashSet<>(Arrays.asList("Foo", "Bar", "Baz", "Qux"));
+
+ System.out.println("Set before shuffling:");
+ System.out.println(students);
+
+ List studentList = new ArrayList<>(students);
+
+ Collections.shuffle(studentList);
+ System.out.println("Shuffled set elements:");
+ System.out.println(studentList);
+ }
+
+ @Test
+ public void whenShufflingWithSameRandomness_thenElementsAreShuffledDeterministically() {
+ List students_1 = Arrays.asList("Foo", "Bar", "Baz", "Qux");
+ List students_2 = Arrays.asList("Foo", "Bar", "Baz", "Qux");
+
+ Collections.shuffle(students_1, new Random(5));
+ Collections.shuffle(students_2, new Random(5));
+
+ assertThat(students_1).isEqualTo(students_2);
+ }
+}
diff --git a/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java b/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java
new file mode 100644
index 0000000000..479f62cb4e
--- /dev/null
+++ b/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java
@@ -0,0 +1,17 @@
+package com.baeldung.java9.methodhandles;
+
+public class Book {
+
+ String id;
+ String title;
+
+ public Book(String id, String title) {
+ this.id = id;
+ this.title = title;
+ }
+
+ @SuppressWarnings("unused")
+ private String formatBook() {
+ return id + " > " + title;
+ }
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java
deleted file mode 100644
index 4a704139a1..0000000000
--- a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package com.baeldung.java9.httpclient;
-
-import static java.net.HttpURLConnection.HTTP_OK;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.net.CookieManager;
-import java.net.CookiePolicy;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.http.HttpClient;
-import java.net.http.HttpHeaders;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.security.NoSuchAlgorithmException;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class SimpleHttpRequestsUnitTest {
-
- private URI httpURI;
-
- @Before
- public void init() throws URISyntaxException {
- httpURI = new URI("http://www.baeldung.com/");
- }
-
- @Test
- public void quickGet() throws IOException, InterruptedException, URISyntaxException {
- HttpRequest request = HttpRequest.create(httpURI).GET();
- HttpResponse response = request.response();
- int responseStatusCode = response.statusCode();
- String responseBody = response.body(HttpResponse.asString());
- assertTrue("Get response status code is bigger then 400", responseStatusCode < 400);
- }
-
- @Test
- public void asynchronousGet() throws URISyntaxException, IOException, InterruptedException, ExecutionException {
- HttpRequest request = HttpRequest.create(httpURI).GET();
- long before = System.currentTimeMillis();
- CompletableFuture futureResponse = request.responseAsync();
- futureResponse.thenAccept(response -> {
- String responseBody = response.body(HttpResponse.asString());
- });
- HttpResponse resp = futureResponse.get();
- HttpHeaders hs = resp.headers();
- assertTrue("There should be more then 1 header.", hs.map().size() > 1);
- }
-
- @Test
- public void postMehtod() throws URISyntaxException, IOException, InterruptedException {
- HttpRequest.Builder requestBuilder = HttpRequest.create(httpURI);
- requestBuilder.body(HttpRequest.fromString("param1=foo,param2=bar")).followRedirects(HttpClient.Redirect.SECURE);
- HttpRequest request = requestBuilder.POST();
- HttpResponse response = request.response();
- int statusCode = response.statusCode();
- assertTrue("HTTP return code", statusCode == HTTP_OK);
- }
-
- @Test
- public void configureHttpClient() throws NoSuchAlgorithmException, URISyntaxException, IOException, InterruptedException {
- CookieManager cManager = new CookieManager();
- cManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
-
- SSLParameters sslParam = new SSLParameters(new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" }, new String[] { "TLSv1.2" });
-
- HttpClient.Builder hcBuilder = HttpClient.create();
- hcBuilder.cookieManager(cManager).sslContext(SSLContext.getDefault()).sslParameters(sslParam);
- HttpClient httpClient = hcBuilder.build();
- HttpRequest.Builder reqBuilder = httpClient.request(new URI("https://www.facebook.com"));
-
- HttpRequest request = reqBuilder.followRedirects(HttpClient.Redirect.ALWAYS).GET();
- HttpResponse response = request.response();
- int statusCode = response.statusCode();
- assertTrue("HTTP return code", statusCode == HTTP_OK);
- }
-
- SSLParameters getDefaultSSLParameters() throws NoSuchAlgorithmException {
- SSLParameters sslP1 = SSLContext.getDefault().getSupportedSSLParameters();
- String[] proto = sslP1.getApplicationProtocols();
- String[] cifers = sslP1.getCipherSuites();
- System.out.println(printStringArr(proto));
- System.out.println(printStringArr(cifers));
- return sslP1;
- }
-
- String printStringArr(String... args) {
- if (args == null) {
- return null;
- }
- StringBuilder sb = new StringBuilder();
- for (String s : args) {
- sb.append(s);
- sb.append("\n");
- }
- return sb.toString();
- }
-
- String printHeaders(HttpHeaders h) {
- if (h == null) {
- return null;
- }
-
- StringBuilder sb = new StringBuilder();
- Map> hMap = h.map();
- for (String k : hMap.keySet()) {
- sb.append(k).append(":");
- List l = hMap.get(k);
- if (l != null) {
- l.forEach(s -> {
- sb.append(s).append(",");
- });
- }
- sb.append("\n");
- }
- return sb.toString();
- }
-}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java b/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java
new file mode 100644
index 0000000000..7646755358
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java
@@ -0,0 +1,152 @@
+package com.baeldung.java9.methodhandles;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * Test case for the {@link MethodHandles} API
+ */
+public class MethodHandlesTest {
+
+ @Test
+ public void givenConcatMethodHandle_whenInvoked_thenCorrectlyConcatenated() throws Throwable {
+
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(String.class, String.class);
+ MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt);
+
+ String output = (String) concatMH.invoke("Effective ", "Java");
+
+ assertEquals("Effective Java", output);
+ }
+
+ @Test
+ public void givenAsListMethodHandle_whenInvokingWithArguments_thenCorrectlyInvoked() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(List.class, Object[].class);
+ MethodHandle asListMH = publicLookup.findStatic(Arrays.class, "asList", mt);
+
+ List list = (List) asListMH.invokeWithArguments(1, 2);
+
+ assertThat(Arrays.asList(1, 2), is(list));
+ }
+
+ @Test
+ public void givenConstructorMethodHandle_whenInvoked_thenObjectCreatedCorrectly() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(void.class, String.class);
+ MethodHandle newIntegerMH = publicLookup.findConstructor(Integer.class, mt);
+
+ Integer integer = (Integer) newIntegerMH.invoke("1");
+
+ assertEquals(1, integer.intValue());
+ }
+
+ @Test
+ public void givenAFieldWithoutGetter_whenCreatingAGetter_thenCorrectlyInvoked() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodHandle getTitleMH = lookup.findGetter(Book.class, "title", String.class);
+
+ Book book = new Book("ISBN-1234", "Effective Java");
+
+ assertEquals("Effective Java", getTitleMH.invoke(book));
+ }
+
+ @Test
+ public void givenPrivateMethod_whenCreatingItsMethodHandle_thenCorrectlyInvoked() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ Method formatBookMethod = Book.class.getDeclaredMethod("formatBook");
+ formatBookMethod.setAccessible(true);
+
+ MethodHandle formatBookMH = lookup.unreflect(formatBookMethod);
+
+ Book book = new Book("ISBN-123", "Java in Action");
+
+ assertEquals("ISBN-123 > Java in Action", formatBookMH.invoke(book));
+ }
+
+ @Test
+ public void givenReplaceMethod_whenUsingReflectionAndInvoked_thenCorrectlyReplaced() throws Throwable {
+ Method replaceMethod = String.class.getMethod("replace", char.class, char.class);
+
+ String string = (String) replaceMethod.invoke("jovo", 'o', 'a');
+
+ assertEquals("java", string);
+ }
+
+ @Test
+ public void givenReplaceMethodHandle_whenInvoked_thenCorrectlyReplaced() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(String.class, char.class, char.class);
+ MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt);
+
+ String replacedString = (String) replaceMH.invoke("jovo", Character.valueOf('o'), 'a');
+
+ assertEquals("java", replacedString);
+ }
+
+ @Test
+ public void givenReplaceMethodHandle_whenInvokingExact_thenCorrectlyReplaced() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(String.class, char.class, char.class);
+ MethodHandle replaceMH = lookup.findVirtual(String.class, "replace", mt);
+
+ String s = (String) replaceMH.invokeExact("jovo", 'o', 'a');
+
+ assertEquals("java", s);
+ }
+
+ @Test
+ public void givenSumMethodHandle_whenInvokingExact_thenSumIsCorrect() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class);
+ MethodHandle sumMH = lookup.findStatic(Integer.class, "sum", mt);
+
+ int sum = (int) sumMH.invokeExact(1, 11);
+
+ assertEquals(12, sum);
+ }
+
+ @Test(expected = WrongMethodTypeException.class)
+ public void givenSumMethodHandleAndIncompatibleArguments_whenInvokingExact_thenException() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class);
+ MethodHandle sumMH = lookup.findStatic(Integer.class, "sum", mt);
+
+ sumMH.invokeExact(Integer.valueOf(1), 11);
+ }
+
+ @Test
+ public void givenSpreadedEqualsMethodHandle_whenInvokedOnArray_thenCorrectlyEvaluated() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(boolean.class, Object.class);
+ MethodHandle equalsMH = publicLookup.findVirtual(String.class, "equals", mt);
+
+ MethodHandle methodHandle = equalsMH.asSpreader(Object[].class, 2);
+
+ assertTrue((boolean) methodHandle.invoke(new Object[] { "java", "java" }));
+ assertFalse((boolean) methodHandle.invoke(new Object[] { "java", "jova" }));
+ }
+
+ @Test
+ public void givenConcatMethodHandle_whenBindToAString_thenCorrectlyConcatenated() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(String.class, String.class);
+ MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt);
+
+ MethodHandle bindedConcatMH = concatMH.bindTo("Hello ");
+
+ assertEquals("Hello World!", bindedConcatMH.invoke("World!"));
+ }
+}
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java
index a70041ed7d..9900d1c63d 100644
--- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java
@@ -16,7 +16,8 @@ public class Job implements Runnable {
@Override
public void run() {
try {
- System.out.println("Job:" + jobName + " Priority:" + jobPriority);
+ System.out.println("Job:" + jobName +
+ " Priority:" + jobPriority);
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java
index 70fd1710c0..ba55696d5a 100644
--- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java
@@ -9,21 +9,21 @@ import java.util.concurrent.TimeUnit;
public class PriorityJobScheduler {
private ExecutorService priorityJobPoolExecutor;
- private ExecutorService priorityJobScheduler;
- private PriorityBlockingQueue priorityQueue;
+ private ExecutorService priorityJobScheduler =
+ Executors.newSingleThreadExecutor();
+ private PriorityBlockingQueue priorityQueue;
public PriorityJobScheduler(Integer poolSize, Integer queueSize) {
priorityJobPoolExecutor = Executors.newFixedThreadPool(poolSize);
- Comparator super Job> jobComparator = Comparator.comparing(Job::getJobPriority);
- priorityQueue = new PriorityBlockingQueue(queueSize,
- (Comparator super Runnable>) jobComparator);
+ priorityQueue = new PriorityBlockingQueue(queueSize,
+ Comparator.comparing(Job::getJobPriority));
- priorityJobScheduler = Executors.newSingleThreadExecutor();
priorityJobScheduler.execute(()->{
while (true) {
try {
priorityJobPoolExecutor.execute(priorityQueue.take());
} catch (InterruptedException e) {
+ // exception needs special handling
break;
}
}
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java
new file mode 100644
index 0000000000..19c6d08c2d
--- /dev/null
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java
@@ -0,0 +1,31 @@
+package com.baeldung.concurrent.threadlifecycle;
+
+public class BlockedState {
+ public static void main(String[] args) throws InterruptedException {
+ Thread t1 = new Thread(new DemoThreadB());
+ Thread t2 = new Thread(new DemoThreadB());
+
+ t1.start();
+ t2.start();
+
+ Thread.sleep(1000);
+
+ System.out.println(t2.getState());
+ System.exit(0);
+ }
+}
+
+class DemoThreadB implements Runnable {
+ @Override
+ public void run() {
+ commonResource();
+ }
+
+ public static synchronized void commonResource() {
+ while(true) {
+ // Infinite loop to mimic heavy processing
+ // Thread 't1' won't leave this method
+ // when Thread 't2' enters this
+ }
+ }
+}
\ No newline at end of file
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java
new file mode 100644
index 0000000000..b524cc5ec7
--- /dev/null
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java
@@ -0,0 +1,14 @@
+package com.baeldung.concurrent.threadlifecycle;
+
+public class NewState implements Runnable {
+ public static void main(String[] args) {
+ Runnable runnable = new NewState();
+ Thread t = new Thread(runnable);
+ System.out.println(t.getState());
+ }
+
+ @Override
+ public void run() {
+
+ }
+}
\ No newline at end of file
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java
new file mode 100644
index 0000000000..4aa8b36a76
--- /dev/null
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java
@@ -0,0 +1,15 @@
+package com.baeldung.concurrent.threadlifecycle;
+
+public class RunnableState implements Runnable {
+ public static void main(String[] args) {
+ Runnable runnable = new NewState();
+ Thread t = new Thread(runnable);
+ t.start();
+ System.out.println(t.getState());
+ }
+
+ @Override
+ public void run() {
+
+ }
+}
\ No newline at end of file
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java
new file mode 100644
index 0000000000..7c8884dc22
--- /dev/null
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java
@@ -0,0 +1,15 @@
+package com.baeldung.concurrent.threadlifecycle;
+
+public class TerminatedState implements Runnable {
+ public static void main(String[] args) throws InterruptedException {
+ Thread t1 = new Thread(new TerminatedState());
+ t1.start();
+ Thread.sleep(1000);
+ System.out.println(t1.getState());
+ }
+
+ @Override
+ public void run() {
+ // No processing in this block
+ }
+}
\ No newline at end of file
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java
new file mode 100644
index 0000000000..8d005352eb
--- /dev/null
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java
@@ -0,0 +1,25 @@
+package com.baeldung.concurrent.threadlifecycle;
+
+public class TimedWaitingState {
+ public static void main(String[] args) throws InterruptedException {
+ DemoThread obj1 = new DemoThread();
+ Thread t1 = new Thread(obj1);
+ t1.start();
+ // The following sleep will give enough time for ThreadScheduler
+ // to start processing of thread t1
+ Thread.sleep(1000);
+ System.out.println(t1.getState());
+ }
+}
+
+class DemoThread implements Runnable {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java
new file mode 100644
index 0000000000..98a6844309
--- /dev/null
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java
@@ -0,0 +1,35 @@
+package com.baeldung.concurrent.threadlifecycle;
+
+public class WaitingState implements Runnable {
+ public static Thread t1;
+
+ public static void main(String[] args) {
+ t1 = new Thread(new WaitingState());
+ t1.start();
+ }
+
+ public void run() {
+ Thread t2 = new Thread(new DemoThreadWS());
+ t2.start();
+
+ try {
+ t2.join();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ e.printStackTrace();
+ }
+ }
+}
+
+class DemoThreadWS implements Runnable {
+ public void run() {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ e.printStackTrace();
+ }
+
+ System.out.println(WaitingState.t1.getState());
+ }
+}
\ No newline at end of file
diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java
index 902bada3a2..1e67fe45c1 100644
--- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java
+++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java
@@ -30,7 +30,9 @@ public class PriorityJobSchedulerUnitTest {
// delay to avoid job sleep (added for demo) being interrupted
try {
Thread.sleep(2000);
- } catch (InterruptedException ignored) {
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
}
pjs.closeScheduler();
diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadManualTest.java
similarity index 97%
rename from core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java
rename to core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadManualTest.java
index af54d6932e..9ea40824ca 100644
--- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java
+++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadManualTest.java
@@ -10,7 +10,7 @@ import org.junit.Test;
import com.jayway.awaitility.Awaitility;
-public class StopThreadTest {
+public class StopThreadManualTest {
@Test
public void whenStoppedThreadIsStopped() throws InterruptedException {
diff --git a/core-java/README.md b/core-java/README.md
index ed60db855c..5be4e12592 100644
--- a/core-java/README.md
+++ b/core-java/README.md
@@ -127,3 +127,5 @@
- [Polymorphism in Java](http://www.baeldung.com/java-polymorphism)
- [Recursion In Java](http://www.baeldung.com/java-recursion)
- [A Guide to the finalize Method in Java](http://www.baeldung.com/java-finalize)
+- [Compiling Java *.class Files with javac](http://www.baeldung.com/javac)
+- [Method Overloading and Overriding in Java](http://www.baeldung.com/java-method-overload-override)
diff --git a/core-java/pom.xml b/core-java/pom.xml
index 5c1e9fcad0..e2983de9dd 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -78,6 +78,11 @@
jackson-databind${jackson.version}
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+
@@ -468,6 +473,7 @@
2.8.5
+ 2.8.21.7.21
diff --git a/core-java/src/main/java/com/baeldung/casting/Animal.java b/core-java/src/main/java/com/baeldung/casting/Animal.java
new file mode 100644
index 0000000000..9f31c1dda3
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/casting/Animal.java
@@ -0,0 +1,13 @@
+package com.baeldung.casting;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Animal {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Animal.class);
+
+ public void eat() {
+ LOGGER.info("animal is eating");
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/casting/AnimalFeeder.java b/core-java/src/main/java/com/baeldung/casting/AnimalFeeder.java
new file mode 100644
index 0000000000..89b972e5c2
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/casting/AnimalFeeder.java
@@ -0,0 +1,23 @@
+package com.baeldung.casting;
+
+import java.util.List;
+
+public class AnimalFeeder {
+
+ public void feed(List animals) {
+ animals.forEach(animal -> {
+ animal.eat();
+ if (animal instanceof Cat) {
+ ((Cat) animal).meow();
+ }
+ });
+ }
+
+ public void uncheckedFeed(List animals) {
+ animals.forEach(animal -> {
+ animal.eat();
+ ((Cat) animal).meow();
+ });
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/casting/Cat.java b/core-java/src/main/java/com/baeldung/casting/Cat.java
new file mode 100644
index 0000000000..aa9a9a881a
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/casting/Cat.java
@@ -0,0 +1,16 @@
+package com.baeldung.casting;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Cat extends Animal implements Mew {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Cat.class);
+
+ public void eat() {
+ LOGGER.info("cat is eating");
+ }
+
+ public void meow() {
+ LOGGER.info("meow");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/casting/Dog.java b/core-java/src/main/java/com/baeldung/casting/Dog.java
new file mode 100644
index 0000000000..763c6b4785
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/casting/Dog.java
@@ -0,0 +1,12 @@
+package com.baeldung.casting;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Dog extends Animal {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Dog.class);
+
+ public void eat() {
+ LOGGER.info("dog is eating");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/casting/Mew.java b/core-java/src/main/java/com/baeldung/casting/Mew.java
new file mode 100644
index 0000000000..f3c7324551
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/casting/Mew.java
@@ -0,0 +1,5 @@
+package com.baeldung.casting;
+
+public interface Mew {
+ public void meow();
+}
diff --git a/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java b/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java
new file mode 100644
index 0000000000..c44e863776
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java
@@ -0,0 +1,29 @@
+package com.baeldung.classloader;
+
+import java.io.*;
+
+public class CustomClassLoader extends ClassLoader {
+
+
+ public Class getClass(String name) throws ClassNotFoundException {
+ byte[] b = loadClassFromFile(name);
+ return defineClass(name, b, 0, b.length);
+ }
+
+ private byte[] loadClassFromFile(String fileName) {
+ InputStream inputStream = getClass().getClassLoader().getResourceAsStream(
+ fileName.replace('.', File.separatorChar) + ".class");
+ byte[] buffer;
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ int nextValue = 0;
+ try {
+ while ( (nextValue = inputStream.read()) != -1 ) {
+ byteStream.write(nextValue);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ buffer = byteStream.toByteArray();
+ return buffer;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/classloader/PrintClassLoader.java b/core-java/src/main/java/com/baeldung/classloader/PrintClassLoader.java
new file mode 100644
index 0000000000..09ee68bf6e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/classloader/PrintClassLoader.java
@@ -0,0 +1,22 @@
+package com.baeldung.classloader;
+
+import com.sun.javafx.util.Logging;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+
+public class PrintClassLoader {
+
+ public void printClassLoaders() throws ClassNotFoundException {
+
+ System.out.println("Classloader of this class:" + PrintClassLoader.class.getClassLoader());
+ System.out.println("Classloader of Logging:" + Logging.class.getClassLoader());
+ System.out.println("Classloader of ArrayList:" + ArrayList.class.getClassLoader());
+
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/deepcopy/Address.java b/core-java/src/main/java/com/baeldung/deepcopy/Address.java
new file mode 100644
index 0000000000..4e010ea92b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/deepcopy/Address.java
@@ -0,0 +1,59 @@
+package com.baeldung.deepcopy;
+
+import java.io.Serializable;
+
+public class Address implements Serializable, Cloneable {
+
+ @Override
+ public Object clone() {
+ try {
+ return (Address) super.clone();
+ } catch (CloneNotSupportedException e) {
+ return new Address(this.street, this.getCity(), this.getCountry());
+ }
+ }
+
+ private static final long serialVersionUID = 1740913841244949416L;
+ private String street;
+ private String city;
+
+ private String country;
+
+ public Address(Address that) {
+ this(that.getStreet(), that.getCity(), that.getCountry());
+ }
+
+ public Address(String street, String city, String country) {
+ this.street = street;
+ this.city = city;
+ this.country = country;
+ }
+
+ public Address() {
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+}
+
diff --git a/core-java/src/main/java/com/baeldung/deepcopy/User.java b/core-java/src/main/java/com/baeldung/deepcopy/User.java
new file mode 100644
index 0000000000..329cfc6b27
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/deepcopy/User.java
@@ -0,0 +1,48 @@
+package com.baeldung.deepcopy;
+
+import java.io.Serializable;
+
+public class User implements Serializable, Cloneable {
+
+ private static final long serialVersionUID = -3427002229954777557L;
+ private String firstName;
+ private String lastName;
+ private Address address;
+
+ public User(String firstName, String lastName, Address address) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.address = address;
+ }
+
+ public User(User that) {
+ this(that.getFirstName(), that.getLastName(), new Address(that.getAddress()));
+ }
+
+ public User() {
+ }
+
+ @Override
+ public Object clone() {
+ User user;
+ try {
+ user = (User) super.clone();
+ } catch (CloneNotSupportedException e) {
+ user = new User(this.getFirstName(), this.getLastName(), this.getAddress());
+ }
+ user.address = (Address) this.address.clone();
+ return user;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/AuthenticationProcessor.java b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/AuthenticationProcessor.java
new file mode 100644
index 0000000000..b86a572393
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/AuthenticationProcessor.java
@@ -0,0 +1,13 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+public abstract class AuthenticationProcessor {
+
+ // next element in chain or responsibility
+ public AuthenticationProcessor nextProcessor;
+
+ public AuthenticationProcessor(AuthenticationProcessor nextProcessor) {
+ this.nextProcessor = nextProcessor;
+ }
+
+ public abstract boolean isAuthorized(AuthenticationProvider authProvider);
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/AuthenticationProvider.java b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/AuthenticationProvider.java
new file mode 100644
index 0000000000..552a7ff6d9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/AuthenticationProvider.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+public interface AuthenticationProvider {
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/OAuthAuthenticationProcessor.java b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/OAuthAuthenticationProcessor.java
new file mode 100644
index 0000000000..2e2e51fed2
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/OAuthAuthenticationProcessor.java
@@ -0,0 +1,21 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+public class OAuthAuthenticationProcessor extends AuthenticationProcessor {
+
+ public OAuthAuthenticationProcessor(AuthenticationProcessor nextProcessor) {
+ super(nextProcessor);
+ }
+
+ @Override
+ public boolean isAuthorized(AuthenticationProvider authProvider) {
+
+ if (authProvider instanceof OAuthTokenProvider) {
+ return Boolean.TRUE;
+ } else if (nextProcessor != null) {
+ return nextProcessor.isAuthorized(authProvider);
+ } else {
+ return Boolean.FALSE;
+ }
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/OAuthTokenProvider.java b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/OAuthTokenProvider.java
new file mode 100644
index 0000000000..d4e516053b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/OAuthTokenProvider.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+public class OAuthTokenProvider implements AuthenticationProvider {
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/SamlAuthenticationProvider.java b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/SamlAuthenticationProvider.java
new file mode 100644
index 0000000000..533b2b4a2d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/SamlAuthenticationProvider.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+public class SamlAuthenticationProvider implements AuthenticationProvider {
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java
new file mode 100644
index 0000000000..df600c35db
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java
@@ -0,0 +1,20 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+public class UsernamePasswordAuthenticationProcessor extends AuthenticationProcessor {
+
+ public UsernamePasswordAuthenticationProcessor(AuthenticationProcessor nextProcessor) {
+ super(nextProcessor);
+ }
+
+ @Override
+ public boolean isAuthorized(AuthenticationProvider authProvider) {
+ if (authProvider instanceof UsernamePasswordProvider) {
+ return Boolean.TRUE;
+ } else if (nextProcessor != null) {
+ return nextProcessor.isAuthorized(authProvider);
+ } else {
+ return Boolean.FALSE;
+ }
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/UsernamePasswordProvider.java b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/UsernamePasswordProvider.java
new file mode 100644
index 0000000000..9fbfa7554d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/chainofresponsibility/UsernamePasswordProvider.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+public class UsernamePasswordProvider implements AuthenticationProvider {
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java
new file mode 100644
index 0000000000..50f62cafaa
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java
@@ -0,0 +1,85 @@
+package com.baeldung.designpatterns.flyweight;
+
+import java.awt.Color;
+
+import javax.annotation.concurrent.Immutable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a car. This class is immutable.
+ *
+ * @author Donato Rimenti
+ */
+@Immutable
+public class Car implements Vehicle {
+
+ /**
+ * Logger.
+ */
+ private final static Logger LOG = LoggerFactory.getLogger(Car.class);
+
+ /**
+ * The car's engine.
+ */
+ private Engine engine;
+
+ /**
+ * The car's color.
+ */
+ private Color color;
+
+ /**
+ * Instantiates a new Car.
+ *
+ * @param engine
+ * the {@link #engine}
+ * @param color
+ * the {@link #color}
+ */
+ public Car(Engine engine, Color color) {
+ this.engine = engine;
+ this.color = color;
+
+ // Building a new car is a very expensive operation!
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ LOG.error("Error while creating a new car", e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.baeldung.designpatterns.flyweight.Vehicle#start()
+ */
+ @Override
+ public void start() {
+ LOG.info("Car is starting!");
+ engine.start();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.baeldung.designpatterns.flyweight.Vehicle#stop()
+ */
+ @Override
+ public void stop() {
+ LOG.info("Car is stopping!");
+ engine.stop();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.baeldung.designpatterns.flyweight.Vehicle#getColor()
+ */
+ @Override
+ public Color getColor() {
+ return this.color;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java
new file mode 100644
index 0000000000..05d9ca98b8
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java
@@ -0,0 +1,31 @@
+package com.baeldung.designpatterns.flyweight;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Engine for a vehicle.
+ *
+ * @author Donato Rimenti
+ */
+public class Engine {
+
+ /**
+ * Logger.
+ */
+ private final static Logger LOG = LoggerFactory.getLogger(Engine.class);
+
+ /**
+ * Starts the engine.
+ */
+ public void start() {
+ LOG.info("Engine is starting!");
+ }
+
+ /**
+ * Stops the engine.
+ */
+ public void stop() {
+ LOG.info("Engine is stopping!");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java
new file mode 100644
index 0000000000..c285f9fcff
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java
@@ -0,0 +1,29 @@
+package com.baeldung.designpatterns.flyweight;
+
+import java.awt.Color;
+
+/**
+ * Interface for a vehicle.
+ *
+ * @author Donato Rimenti
+ */
+public interface Vehicle {
+
+ /**
+ * Starts the vehicle.
+ */
+ public void start();
+
+ /**
+ * Stops the vehicle.
+ */
+ public void stop();
+
+ /**
+ * Gets the color of the vehicle.
+ *
+ * @return the color of the vehicle
+ */
+ public Color getColor();
+
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java
new file mode 100644
index 0000000000..2854b7dab1
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java
@@ -0,0 +1,45 @@
+package com.baeldung.designpatterns.flyweight;
+
+import java.awt.Color;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Factory which implements the Flyweight pattern to return an existing vehicle
+ * if present or a new one otherwise.
+ *
+ * @author Donato Rimenti
+ */
+public class VehicleFactory {
+
+ /**
+ * Stores the already created vehicles.
+ */
+ private static Map vehiclesCache = new HashMap();
+
+ /**
+ * Private constructor to prevent this class instantiation.
+ */
+ private VehicleFactory() {
+ }
+
+ /**
+ * Returns a vehicle of the same color passed as argument. If that vehicle
+ * was already created by this factory, that vehicle is returned, otherwise
+ * a new one is created and returned.
+ *
+ * @param color
+ * the color of the vehicle to return
+ * @return a vehicle of the specified color
+ */
+ public static Vehicle createVehicle(Color color) {
+ // Looks for the requested vehicle into the cache.
+ // If the vehicle doesn't exist, a new one is created.
+ Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> {
+ // Creates the new car.
+ Engine newEngine = new Engine();
+ return new Car(newEngine, newColor);
+ });
+ return newVehicle;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java b/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java
new file mode 100644
index 0000000000..b6bb5181b8
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java
@@ -0,0 +1,43 @@
+package com.baeldung.inheritance;
+
+public class ArmoredCar extends Car implements Floatable, Flyable{
+ private int bulletProofWindows;
+ private String model;
+
+ public void remoteStartCar() {
+ // this vehicle can be started by using a remote control
+ }
+
+ public String registerModel() {
+ return model;
+ }
+
+ public String getAValue() {
+ return super.model; // returns value of model defined in base class Car
+ // return this.model; // will return value of model defined in ArmoredCar
+ // return model; // will return value of model defined in ArmoredCar
+ }
+
+ public static String msg() {
+ // return super.msg(); // this won't compile.
+ return "ArmoredCar";
+ }
+
+ @Override
+ public void floatOnWater() {
+ System.out.println("I can float!");
+ }
+
+ @Override
+ public void fly() {
+ System.out.println("I can fly!");
+ }
+
+ public void aMethod() {
+ // System.out.println(duration); // Won't compile
+ System.out.println(Floatable.duration); // outputs 10
+ System.out.println(Flyable.duration); // outputs 20
+ }
+
+
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/BMW.java b/core-java/src/main/java/com/baeldung/inheritance/BMW.java
new file mode 100644
index 0000000000..8ad3bb683f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/BMW.java
@@ -0,0 +1,12 @@
+package com.baeldung.inheritance;
+
+public class BMW extends Car {
+ public BMW() {
+ super(5, "BMW");
+ }
+
+ @Override
+ public String toString() {
+ return model;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Car.java b/core-java/src/main/java/com/baeldung/inheritance/Car.java
new file mode 100644
index 0000000000..21ea9ea569
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Car.java
@@ -0,0 +1,32 @@
+package com.baeldung.inheritance;
+
+public class Car {
+ private final int DEFAULT_WHEEL_COUNT = 5;
+ private final String DEFAULT_MODEL = "Basic";
+
+ protected int wheels;
+ protected String model;
+
+ public Car() {
+ this.wheels = DEFAULT_WHEEL_COUNT;
+ this.model = DEFAULT_MODEL;
+ }
+
+ public Car(int wheels, String model) {
+ this.wheels = wheels;
+ this.model = model;
+ }
+
+ public void start() {
+ // Check essential parts
+ // If okay, start.
+ }
+ public static int count = 10;
+ public static String msg() {
+ return "Car";
+ }
+
+ public String toString() {
+ return model;
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Employee.java b/core-java/src/main/java/com/baeldung/inheritance/Employee.java
new file mode 100644
index 0000000000..599a1d7331
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Employee.java
@@ -0,0 +1,15 @@
+package com.baeldung.inheritance;
+
+public class Employee {
+ private String name;
+ private Car car;
+
+ public Employee(String name, Car car) {
+ this.name = name;
+ this.car = car;
+ }
+
+ public Car getCar() {
+ return car;
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Floatable.java b/core-java/src/main/java/com/baeldung/inheritance/Floatable.java
new file mode 100644
index 0000000000..c0b456dffb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Floatable.java
@@ -0,0 +1,10 @@
+package com.baeldung.inheritance;
+
+public interface Floatable {
+ int duration = 10;
+ void floatOnWater();
+
+ default void repair() {
+ System.out.println("Repairing Floatable object");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Flyable.java b/core-java/src/main/java/com/baeldung/inheritance/Flyable.java
new file mode 100644
index 0000000000..cb8244cf5b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Flyable.java
@@ -0,0 +1,13 @@
+package com.baeldung.inheritance;
+
+public interface Flyable {
+ int duration = 10;
+ void fly();
+
+ /*
+ * Commented
+ */
+ //default void repair() {
+ // System.out.println("Repairing Flyable object");
+ //}
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java b/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java
new file mode 100644
index 0000000000..8c23b26da9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java
@@ -0,0 +1,18 @@
+package com.baeldung.inheritance;
+
+public class SpaceCar extends Car implements SpaceTraveller {
+ @Override
+ public void floatOnWater() {
+ System.out.println("SpaceCar floating!");
+ }
+
+ @Override
+ public void fly() {
+ System.out.println("SpaceCar flying!");
+ }
+
+ @Override
+ public void remoteControl() {
+ System.out.println("SpaceCar being controlled remotely!");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java b/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java
new file mode 100644
index 0000000000..9b66441791
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java
@@ -0,0 +1,6 @@
+package com.baeldung.inheritance;
+
+public interface SpaceTraveller extends Floatable, Flyable {
+ int duration = 10;
+ void remoteControl();
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/java/list/CustomList.java b/core-java/src/main/java/com/baeldung/java/list/CustomList.java
new file mode 100644
index 0000000000..8b91fca32f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/list/CustomList.java
@@ -0,0 +1,210 @@
+package com.baeldung.java.list;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+public class CustomList implements List {
+ private Object[] internal = {};
+
+ @Override
+ public boolean isEmpty() {
+ // the first cycle
+ // return true;
+
+ // the second cycle
+ // if (internal.length != 0) {
+ // return false;
+ // } else {
+ // return true;
+ // }
+
+ // refactoring
+ return internal.length == 0;
+ }
+
+ @Override
+ public int size() {
+ // the first cycle
+ // if (isEmpty()) {
+ // return 0;
+ // } else {
+ // return internal.length;
+ // }
+
+ // refactoring
+ return internal.length;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public E get(int index) {
+ // the first cycle
+ // return (E) internal[0];
+
+ // improvement
+ return (E) internal[index];
+ }
+
+ @Override
+ public boolean add(E element) {
+ // the first cycle
+ // internal = new Object[] { element };
+ // return true;
+
+ // the second cycle
+ Object[] temp = Arrays.copyOf(internal, internal.length + 1);
+ temp[internal.length] = element;
+ internal = temp;
+ return true;
+ }
+
+ @Override
+ public void add(int index, E element) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(Collection extends E> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends E> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public E remove(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeAll(Collection> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean retainAll(Collection> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean contains(Object object) {
+ for (Object element : internal) {
+ if (object.equals(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection> collection) {
+ for (Object element : collection)
+ if (!contains(element)) {
+ return false;
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public E set(int index, E element) {
+ E oldElement = (E) internal[index];
+ internal[index] = element;
+ return oldElement;
+ }
+
+ @Override
+ public void clear() {
+ internal = new Object[0];
+ }
+
+ @Override
+ public int indexOf(Object object) {
+ for (int i = 0; i < internal.length; i++) {
+ if (object.equals(internal[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public int lastIndexOf(Object object) {
+ for (int i = internal.length - 1; i >= 0; i--) {
+ if (object.equals(internal[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List subList(int fromIndex, int toIndex) {
+ Object[] temp = new Object[toIndex - fromIndex];
+ System.arraycopy(internal, fromIndex, temp, 0, temp.length);
+ return (List) Arrays.asList(temp);
+ }
+
+ @Override
+ public Object[] toArray() {
+ return Arrays.copyOf(internal, internal.length);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T[] toArray(T[] array) {
+ if (array.length < internal.length) {
+ return (T[]) Arrays.copyOf(internal, internal.length, array.getClass());
+ }
+
+ System.arraycopy(internal, 0, array, 0, internal.length);
+ if (array.length > internal.length) {
+ array[internal.length] = null;
+ }
+ return array;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new CustomIterator();
+ }
+
+ @Override
+ public ListIterator listIterator() {
+ return null;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ // ignored for brevity
+ return null;
+ }
+
+ private class CustomIterator implements Iterator {
+ int index;
+
+ @Override
+ public boolean hasNext() {
+ return index != internal.length;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public E next() {
+ E element = (E) CustomList.this.internal[index];
+ index++;
+ return element;
+ }
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java
new file mode 100644
index 0000000000..6e023e9fa8
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java
@@ -0,0 +1,26 @@
+package com.baeldung.methodoverloadingoverriding.application;
+
+import com.baeldung.methodoverloadingoverriding.model.Car;
+import com.baeldung.methodoverloadingoverriding.model.Vehicle;
+import com.baeldung.methodoverloadingoverriding.util.Multiplier;
+
+public class Application {
+
+ public static void main(String[] args) {
+ Multiplier multiplier = new Multiplier();
+ System.out.println(multiplier.multiply(10, 10));
+ System.out.println(multiplier.multiply(10, 10, 10));
+ System.out.println(multiplier.multiply(10, 10.5));
+ System.out.println(multiplier.multiply(10.5, 10.5));
+
+ Vehicle vehicle = new Vehicle();
+ System.out.println(vehicle.accelerate(100));
+ System.out.println(vehicle.run());
+ System.out.println(vehicle.stop());
+
+ Vehicle car = new Car();
+ System.out.println(car.accelerate(80));
+ System.out.println(car.run());
+ System.out.println(car.stop());
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java
new file mode 100644
index 0000000000..aa5bdcaec9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java
@@ -0,0 +1,9 @@
+package com.baeldung.methodoverloadingoverriding.model;
+
+public class Car extends Vehicle {
+
+ @Override
+ public String accelerate(long mph) {
+ return "The car accelerates at : " + mph + " MPH.";
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java
new file mode 100644
index 0000000000..eb59e8ca23
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java
@@ -0,0 +1,16 @@
+package com.baeldung.methodoverloadingoverriding.model;
+
+public class Vehicle {
+
+ public String accelerate(long mph) {
+ return "The vehicle accelerates at : " + mph + " MPH.";
+ }
+
+ public String stop() {
+ return "The vehicle has stopped.";
+ }
+
+ public String run() {
+ return "The vehicle is running.";
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java
new file mode 100644
index 0000000000..c43e61c78f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java
@@ -0,0 +1,16 @@
+package com.baeldung.methodoverloadingoverriding.util;
+
+public class Multiplier {
+
+ public int multiply(int a, int b) {
+ return a * b;
+ }
+
+ public int multiply(int a, int b, int c) {
+ return a * b * c;
+ }
+
+ public double multiply(double a, double b) {
+ return a * b;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/recursion/BinaryNode.java b/core-java/src/main/java/com/baeldung/recursion/BinaryNode.java
new file mode 100644
index 0000000000..0c3f0ecc40
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/recursion/BinaryNode.java
@@ -0,0 +1,31 @@
+package com.baeldung.recursion;
+
+public class BinaryNode {
+ int value;
+ BinaryNode left;
+ BinaryNode right;
+
+ public BinaryNode(int value){
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ public void setValue(int value) {
+ this.value = value;
+ }
+ public BinaryNode getLeft() {
+ return left;
+ }
+ public void setLeft(BinaryNode left) {
+ this.left = left;
+ }
+ public BinaryNode getRight() {
+ return right;
+ }
+ public void setRight(BinaryNode right) {
+ this.right = right;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/recursion/RecursionExample.java b/core-java/src/main/java/com/baeldung/recursion/RecursionExample.java
new file mode 100644
index 0000000000..649c0e0587
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/recursion/RecursionExample.java
@@ -0,0 +1,64 @@
+package com.baeldung.recursion;
+
+public class RecursionExample {
+
+ public int sum(int n){
+ if (n >= 1){
+ return sum(n - 1) + n;
+ }
+ return n;
+ }
+
+ public int tailSum(int currentSum, int n){
+ if (n <= 1) {
+ return currentSum + n;
+ }
+ return tailSum(currentSum + n, n - 1);
+ }
+
+ public int iterativeSum(int n){
+ int sum = 0;
+ if(n < 0){
+ return -1;
+ }
+ for(int i=0; i<=n; i++){
+ sum += i;
+ }
+ return sum;
+ }
+
+ public int powerOf10(int n){
+ if (n == 0){
+ return 1;
+ }
+ return powerOf10(n-1)*10;
+ }
+
+ public int fibonacci(int n){
+ if (n <=1 ){
+ return n;
+ }
+ return fibonacci(n-1) + fibonacci(n-2);
+ }
+
+ public String toBinary(int n){
+ if (n <= 1 ){
+ return String.valueOf(n);
+ }
+ return toBinary(n / 2) + String.valueOf(n % 2);
+ }
+
+ public int calculateTreeHeight(BinaryNode root){
+ if (root!= null){
+ if (root.getLeft() != null || root.getRight() != null){
+ return 1 + max(calculateTreeHeight(root.left) , calculateTreeHeight(root.right));
+ }
+ }
+ return 0;
+ }
+
+ public int max(int a,int b){
+ return a>b ? a:b;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java
new file mode 100644
index 0000000000..88ce36c27f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java
@@ -0,0 +1,15 @@
+package com.baeldung.resourcebundle;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+public class ExampleControl extends ResourceBundle.Control {
+
+ @Override
+ public List getCandidateLocales(String s, Locale locale) {
+ return Arrays.asList(new Locale("pl", "PL"));
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java
new file mode 100644
index 0000000000..52ccc80f52
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java
@@ -0,0 +1,14 @@
+package com.baeldung.resourcebundle;
+
+import java.util.ListResourceBundle;
+
+public class ExampleResource extends ListResourceBundle {
+
+ @Override
+ protected Object[][] getContents() {
+ return new Object[][] {
+ { "greeting", "hello" }
+ };
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java
new file mode 100644
index 0000000000..7d4f11a5d3
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java
@@ -0,0 +1,15 @@
+package com.baeldung.resourcebundle;
+
+import java.util.ListResourceBundle;
+
+public class ExampleResource_pl extends ListResourceBundle {
+
+ @Override
+ protected Object[][] getContents() {
+ return new Object[][] {
+ { "greeting", "cześć" },
+ { "language", "polish" },
+ };
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java
new file mode 100644
index 0000000000..252bfcb9cf
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java
@@ -0,0 +1,17 @@
+package com.baeldung.resourcebundle;
+
+import java.math.BigDecimal;
+import java.util.ListResourceBundle;
+
+public class ExampleResource_pl_PL extends ListResourceBundle {
+
+ @Override
+ protected Object[][] getContents() {
+ return new Object[][] {
+ { "currency", "polish zloty" },
+ { "toUsdRate", new BigDecimal("3.401") },
+ { "cities", new String[] { "Warsaw", "Cracow" } }
+ };
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java
new file mode 100644
index 0000000000..97d4d36d07
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java
@@ -0,0 +1,66 @@
+package com.baeldung.string;
+
+import java.util.stream.IntStream;
+
+public class Palindrome {
+
+ public boolean isPalindrome(String text) {
+ String clean = text.replaceAll("\\s+", "").toLowerCase();
+ int length = clean.length();
+ int forward = 0;
+ int backward = length - 1;
+ while (backward > forward) {
+ char forwardChar = clean.charAt(forward++);
+ char backwardChar = clean.charAt(backward--);
+ if (forwardChar != backwardChar)
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isPalindromeReverseTheString(String text) {
+ StringBuilder reverse = new StringBuilder();
+ String clean = text.replaceAll("\\s+", "").toLowerCase();
+ char[] plain = clean.toCharArray();
+ for (int i = plain.length - 1; i >= 0; i--)
+ reverse.append(plain[i]);
+ return (reverse.toString()).equals(clean);
+ }
+
+ public boolean isPalindromeUsingStringBuilder(String text) {
+ String clean = text.replaceAll("\\s+", "").toLowerCase();
+ StringBuilder plain = new StringBuilder(clean);
+ StringBuilder reverse = plain.reverse();
+ return (reverse.toString()).equals(clean);
+ }
+
+ public boolean isPalindromeUsingStringBuffer(String text) {
+ String clean = text.replaceAll("\\s+", "").toLowerCase();
+ StringBuffer plain = new StringBuffer(clean);
+ StringBuffer reverse = plain.reverse();
+ return (reverse.toString()).equals(clean);
+ }
+
+ public boolean isPalindromeRecursive(String text) {
+ String clean = text.replaceAll("\\s+", "").toLowerCase();
+ return recursivePalindrome(clean, 0, clean.length() - 1);
+ }
+
+ private boolean recursivePalindrome(String text, int forward, int backward) {
+ if (forward == backward)
+ return true;
+ if ((text.charAt(forward)) != (text.charAt(backward)))
+ return false;
+ if (forward < backward + 1) {
+ return recursivePalindrome(text, forward + 1, backward - 1);
+ }
+
+ return true;
+ }
+
+ public boolean isPalindromeUsingIntStream(String text) {
+ String temp = text.replaceAll("\\s+", "").toLowerCase();
+ return IntStream.range(0, temp.length() / 2)
+ .noneMatch(i -> temp.charAt(i) != temp.charAt(temp.length() - i - 1));
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/system/DetectOS.java b/core-java/src/main/java/com/baeldung/system/DetectOS.java
new file mode 100644
index 0000000000..2d605fe49f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/system/DetectOS.java
@@ -0,0 +1,18 @@
+package com.baeldung.system;
+
+import org.apache.commons.lang3.SystemUtils;
+
+public class DetectOS {
+
+ public String getOperatingSystem() {
+ String os = System.getProperty("os.name");
+ System.out.println("Using System Property: " + os);
+ return os;
+ }
+
+ public String getOperatingSystemSystemUtils() {
+ String os = SystemUtils.OS_NAME;
+ System.out.println("Using SystemUtils: " + os);
+ return os;
+ }
+}
diff --git a/core-java/src/main/resources/resourcebundle/resource.properties b/core-java/src/main/resources/resourcebundle/resource.properties
new file mode 100644
index 0000000000..edeae3ef4b
--- /dev/null
+++ b/core-java/src/main/resources/resourcebundle/resource.properties
@@ -0,0 +1,6 @@
+# Buttons
+cancelButton=cancel
+continueButton continue
+
+! Labels
+helloLabel:hello
diff --git a/core-java/src/main/resources/resourcebundle/resource_en.properties b/core-java/src/main/resources/resourcebundle/resource_en.properties
new file mode 100644
index 0000000000..5d72b65e2f
--- /dev/null
+++ b/core-java/src/main/resources/resourcebundle/resource_en.properties
@@ -0,0 +1 @@
+deleteButton=delete
\ No newline at end of file
diff --git a/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties b/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties
new file mode 100644
index 0000000000..37dea822ad
--- /dev/null
+++ b/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties
@@ -0,0 +1,3 @@
+backButton=cofnij
+helloLabel=cze\u015b\u0107
+helloLabelNoEncoding=cześć
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/casting/CastingTest.java b/core-java/src/test/java/com/baeldung/casting/CastingTest.java
new file mode 100644
index 0000000000..0ca1ce88dc
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/casting/CastingTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.casting;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CastingTest {
+
+ @Test
+ public void whenPrimitiveConverted_thenValueChanged() {
+ double myDouble = 1.1;
+ int myInt = (int) myDouble;
+ assertNotEquals(myDouble, myInt);
+ }
+
+ @Test
+ public void whenUpcast_thenInstanceUnchanged() {
+ Cat cat = new Cat();
+ Animal animal = cat;
+ animal = (Animal) cat;
+ assertTrue(animal instanceof Cat);
+ }
+
+ @Test
+ public void whenUpcastToObject_thenInstanceUnchanged() {
+ Object object = new Animal();
+ assertTrue(object instanceof Animal);
+ }
+
+ @Test
+ public void whenUpcastToInterface_thenInstanceUnchanged() {
+ Mew mew = new Cat();
+ assertTrue(mew instanceof Cat);
+ }
+
+ @Test
+ public void whenUpcastToAnimal_thenOverridenMethodsCalled() {
+ List animals = new ArrayList<>();
+ animals.add(new Cat());
+ animals.add(new Dog());
+ new AnimalFeeder().feed(animals);
+ }
+
+ @Test
+ public void whenDowncastToCat_thenMeowIsCalled() {
+ Animal animal = new Cat();
+ ((Cat) animal).meow();
+ }
+
+ @Test(expected = ClassCastException.class)
+ public void whenDownCastWithoutCheck_thenExceptionThrown() {
+ List animals = new ArrayList<>();
+ animals.add(new Cat());
+ animals.add(new Dog());
+ new AnimalFeeder().uncheckedFeed(animals);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderTest.java b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderTest.java
new file mode 100644
index 0000000000..9f3c751805
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.classloader;
+
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class CustomClassLoaderTest {
+
+ @Test
+ public void customLoader() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
+
+ CustomClassLoader customClassLoader = new CustomClassLoader();
+ Class> c = customClassLoader.getClass(PrintClassLoader.class.getName());
+
+ Object ob = c.newInstance();
+
+ Method md = c.getMethod("printClassLoaders");
+ md.invoke(ob);
+
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/classloader/PrintClassLoaderTest.java b/core-java/src/test/java/com/baeldung/classloader/PrintClassLoaderTest.java
new file mode 100644
index 0000000000..f44a5cef09
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/classloader/PrintClassLoaderTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.classloader;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class PrintClassLoaderTest {
+ @Test(expected = ClassNotFoundException.class)
+ public void givenAppClassLoader_whenParentClassLoader_thenClassNotFoundException() throws Exception {
+ PrintClassLoader sampleClassLoader = (PrintClassLoader) Class.forName(PrintClassLoader.class.getName()).newInstance();
+ sampleClassLoader.printClassLoaders();
+ Class.forName(PrintClassLoader.class.getName(), true, PrintClassLoader.class.getClassLoader().getParent());
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java b/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java
new file mode 100644
index 0000000000..8acd4e023e
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java
@@ -0,0 +1,116 @@
+package com.baeldung.decimalformat;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Locale;
+
+import org.junit.Test;
+
+public class DecimalFormatExamplesTest {
+
+ double d = 1234567.89;
+
+ @Test
+ public void givenSimpleDecimal_WhenFormatting_ThenCorrectOutput() {
+
+ assertThat(new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1234567.89");
+
+ assertThat(new DecimalFormat("0.00", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1234567.89");
+
+ assertThat(new DecimalFormat("#########.###", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1234567.89");
+
+ assertThat(new DecimalFormat("000000000.000", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("001234567.890");
+
+ }
+
+ @Test
+ public void givenSmallerDecimalPattern_WhenFormatting_ThenRounding() {
+
+ assertThat(new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)).isEqualTo("1234567.9");
+
+ assertThat(new DecimalFormat("#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)).isEqualTo("1234568");
+
+ }
+
+ @Test
+ public void givenGroupingSeparator_WhenFormatting_ThenGroupedOutput() {
+
+ assertThat(new DecimalFormat("#,###.#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1,234,567.9");
+
+ assertThat(new DecimalFormat("#,###", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1,234,568");
+
+ }
+
+ @Test
+ public void givenMixedPattern_WhenFormatting_ThenCorrectOutput() {
+
+ assertThat(new DecimalFormat("The # number", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("The 1234568 number");
+
+ assertThat(new DecimalFormat("The '#' # number", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("The # 1234568 number");
+
+ }
+
+ @Test
+ public void givenLocales_WhenFormatting_ThenCorrectOutput() {
+
+ assertThat(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1,234,567.89");
+
+ assertThat(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ITALIAN)).format(d))
+ .isEqualTo("1.234.567,89");
+
+ assertThat(new DecimalFormat("#,###.##", DecimalFormatSymbols.getInstance(new Locale("it", "IT"))).format(d))
+ .isEqualTo("1.234.567,89");
+
+ }
+
+ @Test
+ public void givenE_WhenFormatting_ThenScientificNotation() {
+
+ assertThat(new DecimalFormat("00.#######E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("12.3456789E5");
+
+ assertThat(new DecimalFormat("000.000000E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("123.456789E4");
+
+ assertThat(new DecimalFormat("##0.######E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1.23456789E6");
+
+ assertThat(new DecimalFormat("###.000000E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d))
+ .isEqualTo("1.23456789E6");
+
+ }
+
+ @Test
+ public void givenString_WhenParsing_ThenCorrectOutput() throws ParseException {
+
+ assertThat(new DecimalFormat("", new DecimalFormatSymbols(Locale.ENGLISH)).parse("1234567.89"))
+ .isEqualTo(1234567.89);
+
+ assertThat(new DecimalFormat("", new DecimalFormatSymbols(Locale.ITALIAN)).parse("1.234.567,89"))
+ .isEqualTo(1234567.89);
+
+ }
+
+ @Test
+ public void givenStringAndBigDecimalFlag_WhenParsing_ThenCorrectOutput() throws ParseException {
+
+ NumberFormat nf = new DecimalFormat("", new DecimalFormatSymbols(Locale.ENGLISH));
+ ((DecimalFormat) nf).setParseBigDecimal(true);
+ assertThat(nf.parse("1234567.89")).isEqualTo(BigDecimal.valueOf(1234567.89));
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/deepcopy/DeepCopyUnitTest.java b/core-java/src/test/java/com/baeldung/deepcopy/DeepCopyUnitTest.java
new file mode 100644
index 0000000000..196b69fbf7
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/deepcopy/DeepCopyUnitTest.java
@@ -0,0 +1,128 @@
+package com.baeldung.deepcopy;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+
+import org.apache.commons.lang.SerializationUtils;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+
+public class DeepCopyUnitTest {
+
+ @Test
+ public void whenCreatingDeepCopyWithCopyConstructor_thenObjectsShouldNotBeSame() {
+
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+
+ User deepCopy = new User(pm);
+
+ assertThat(deepCopy).isNotSameAs(pm);
+ }
+
+ @Test
+ public void whenModifyingOriginalObject_thenConstructorCopyShouldNotChange() {
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+ User deepCopy = new User(pm);
+
+ address.setCountry("Great Britain");
+
+ assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry());
+ }
+
+ @Test
+ public void whenModifyingOriginalObject_thenCloneCopyShouldNotChange() {
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+ User deepCopy = (User) pm.clone();
+
+ address.setCountry("Great Britain");
+
+ assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry());
+ }
+
+ @Test
+ public void whenModifyingOriginalObject_thenCommonsCloneShouldNotChange() {
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+ User deepCopy = (User) SerializationUtils.clone(pm);
+
+ address.setCountry("Great Britain");
+
+ assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry());
+ }
+
+ @Test
+ public void whenModifyingOriginalObject_thenGsonCloneShouldNotChange() {
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+ Gson gson = new Gson();
+ User deepCopy = gson.fromJson(gson.toJson(pm), User.class);
+
+ address.setCountry("Great Britain");
+
+ assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry());
+ }
+
+ @Test
+ public void whenModifyingOriginalObject_thenJacksonCopyShouldNotChange() throws IOException {
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+ ObjectMapper objectMapper = new ObjectMapper();
+ User deepCopy = objectMapper.readValue(objectMapper.writeValueAsString(pm), User.class);
+
+ address.setCountry("Great Britain");
+
+ assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry());
+ }
+
+ @Test
+ @Ignore
+ public void whenMakingCopies_thenShowHowLongEachMethodTakes() throws CloneNotSupportedException, IOException {
+ int times = 1000000;
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < times; i++) {
+ User primeMinisterClone = (User) SerializationUtils.clone(pm);
+ }
+ long end = System.currentTimeMillis();
+ System.out.println("Cloning with Apache Commons Lang took " + (end - start) + " milliseconds.");
+
+ start = System.currentTimeMillis();
+ Gson gson = new Gson();
+ for (int i = 0; i < times; i++) {
+ User primeMinisterClone = gson.fromJson(gson.toJson(pm), User.class);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("Cloning with Gson took " + (end - start) + " milliseconds.");
+
+ start = System.currentTimeMillis();
+ for (int i = 0; i < times; i++) {
+ User primeMinisterClone = new User(pm);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("Cloning with the copy constructor took " + (end - start) + " milliseconds.");
+
+ start = System.currentTimeMillis();
+ for (int i = 0; i < times; i++) {
+ User primeMinisterClone = (User) pm.clone();
+ }
+ end = System.currentTimeMillis();
+ System.out.println("Cloning with Cloneable interface took " + (end - start) + " milliseconds.");
+
+ start = System.currentTimeMillis();
+ ObjectMapper objectMapper = new ObjectMapper();
+ for (int i = 0; i < times; i++) {
+ User primeMinisterClone = objectMapper.readValue(objectMapper.writeValueAsString(pm), User.class);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("Cloning with Jackson took " + (end - start) + " milliseconds.");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/deepcopy/ShallowCopyUnitTest.java b/core-java/src/test/java/com/baeldung/deepcopy/ShallowCopyUnitTest.java
new file mode 100644
index 0000000000..57660fadf1
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/deepcopy/ShallowCopyUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.deepcopy;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class ShallowCopyUnitTest {
+
+
+ @Test
+ public void whenShallowCopying_thenObjectsShouldNotBeSame() {
+
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+
+ User shallowCopy = new User(pm.getFirstName(), pm.getLastName(), pm.getAddress());
+
+ assertThat(shallowCopy)
+ .isNotSameAs(pm);
+ }
+
+ @Test
+ public void whenModifyingOriginalObject_thenCopyShouldChange() {
+ Address address = new Address("Downing St 10", "London", "England");
+ User pm = new User("Prime", "Minister", address);
+ User shallowCopy = new User(pm.getFirstName(), pm.getLastName(), pm.getAddress());
+
+ address.setCountry("Great Britain");
+
+ assertThat(shallowCopy.getAddress().getCountry())
+ .isEqualTo(pm.getAddress().getCountry());
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/chainofresponsibility/ChainOfResponsibilityTest.java b/core-java/src/test/java/com/baeldung/designpatterns/chainofresponsibility/ChainOfResponsibilityTest.java
new file mode 100644
index 0000000000..a28577efb1
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/chainofresponsibility/ChainOfResponsibilityTest.java
@@ -0,0 +1,37 @@
+package com.baeldung.designpatterns.chainofresponsibility;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class ChainOfResponsibilityTest {
+
+ private static AuthenticationProcessor getChainOfAuthProcessor() {
+
+ AuthenticationProcessor oAuthProcessor = new OAuthAuthenticationProcessor(null);
+ AuthenticationProcessor unamePasswordProcessor = new UsernamePasswordAuthenticationProcessor(oAuthProcessor);
+ return unamePasswordProcessor;
+ }
+
+ @Test
+ public void givenOAuthProvider_whenCheckingAuthorized_thenSuccess() {
+ AuthenticationProcessor authProcessorChain = getChainOfAuthProcessor();
+ boolean isAuthorized = authProcessorChain.isAuthorized(new OAuthTokenProvider());
+ assertTrue(isAuthorized);
+ }
+
+ @Test
+ public void givenUsernamePasswordProvider_whenCheckingAuthorized_thenSuccess() {
+ AuthenticationProcessor authProcessorChain = getChainOfAuthProcessor();
+ boolean isAuthorized = authProcessorChain.isAuthorized(new UsernamePasswordProvider());
+ assertTrue(isAuthorized);
+ }
+
+ @Test
+ public void givenSamlAuthProvider_whenCheckingAuthorized_thenFailure() {
+ AuthenticationProcessor authProcessorChain = getChainOfAuthProcessor();
+ boolean isAuthorized = authProcessorChain.isAuthorized(new SamlAuthenticationProvider());
+ assertTrue(!isAuthorized);
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java b/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java
new file mode 100644
index 0000000000..645e2fd459
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.designpatterns.flyweight;
+
+import java.awt.Color;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link VehicleFactory}.
+ *
+ * @author Donato Rimenti
+ */
+public class FlyweightUnitTest {
+
+ /**
+ * Checks that when the {@link VehicleFactory} is asked to provide two
+ * vehicles of different colors, the objects returned are different.
+ */
+ @Test
+ public void givenDifferentFlyweightObjects_whenEquals_thenFalse() {
+ Vehicle blackVehicle = VehicleFactory.createVehicle(Color.BLACK);
+ Vehicle blueVehicle = VehicleFactory.createVehicle(Color.BLUE);
+
+ Assert.assertNotNull("Object returned by the factory is null!", blackVehicle);
+ Assert.assertNotNull("Object returned by the factory is null!", blueVehicle);
+ Assert.assertNotEquals("Objects returned by the factory are equals!", blackVehicle, blueVehicle);
+ }
+
+ /**
+ * Checks that when the {@link VehicleFactory} is asked to provide two
+ * vehicles of the same colors, the same object is returned twice.
+ */
+ @Test
+ public void givenSameFlyweightObjects_whenEquals_thenTrue() {
+ Vehicle blackVehicle = VehicleFactory.createVehicle(Color.BLACK);
+ Vehicle anotherBlackVehicle = VehicleFactory.createVehicle(Color.BLACK);
+
+ Assert.assertNotNull("Object returned by the factory is null!", blackVehicle);
+ Assert.assertNotNull("Object returned by the factory is null!", anotherBlackVehicle);
+ Assert.assertEquals("Objects returned by the factory are not equals!", blackVehicle, anotherBlackVehicle);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/inheritance/AppTest.java b/core-java/src/test/java/com/baeldung/inheritance/AppTest.java
new file mode 100644
index 0000000000..1235761aba
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/inheritance/AppTest.java
@@ -0,0 +1,46 @@
+package com.baeldung.inheritance;
+
+import com.baeldung.inheritance.*;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AppTest extends TestCase {
+
+ public AppTest(String testName) {
+ super( testName );
+ }
+
+ public static Test suite() {
+ return new TestSuite(AppTest.class);
+ }
+
+ @SuppressWarnings("static-access")
+ public void testStaticMethodUsingBaseClassVariable() {
+ Car first = new ArmoredCar();
+ assertEquals("Car", first.msg());
+ }
+
+ @SuppressWarnings("static-access")
+ public void testStaticMethodUsingDerivedClassVariable() {
+ ArmoredCar second = new ArmoredCar();
+ assertEquals("ArmoredCar", second.msg());
+ }
+
+ public void testAssignArmoredCarToCar() {
+ Employee e1 = new Employee("Shreya", new ArmoredCar());
+ assertNotNull(e1.getCar());
+ }
+
+ public void testAssignSpaceCarToCar() {
+ Employee e2 = new Employee("Paul", new SpaceCar());
+ assertNotNull(e2.getCar());
+ }
+
+ public void testBMWToCar() {
+ Employee e3 = new Employee("Pavni", new BMW());
+ assertNotNull(e3.getCar());
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java b/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java
new file mode 100644
index 0000000000..9ea42e88e8
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java
@@ -0,0 +1,296 @@
+package com.baeldung.java.list;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+
+public class CustomListUnitTest {
+ @Test
+ public void givenEmptyList_whenIsEmpty_thenTrueIsReturned() {
+ List
+
+
+ com.github.salomonbrys.kodein
+ kodein
+ ${kodein.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
@@ -189,11 +200,13 @@
1.1.20.151.5.0
+ 4.1.05.0.01.0.04.12.04.12
+ 3.9.1
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt
new file mode 100644
index 0000000000..721bdb04bc
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class Controller(private val service : Service)
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt
new file mode 100644
index 0000000000..a0be7ef0e0
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+interface Dao
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt
new file mode 100644
index 0000000000..0a09b95dbf
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class JdbcDao : Dao
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt
new file mode 100644
index 0000000000..06436fcd21
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class MongoDao : Dao
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt
new file mode 100644
index 0000000000..bb24a5cc21
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class Service(private val dao: Dao, private val tag: String)
\ No newline at end of file
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/InfixFunctionsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/InfixFunctionsTest.kt
new file mode 100644
index 0000000000..fc4286460a
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/InfixFunctionsTest.kt
@@ -0,0 +1,51 @@
+package com.baeldung.kotlin
+
+import org.junit.Assert
+import org.junit.Test
+
+class InfixFunctionsTest {
+ @Test
+ fun testColours() {
+ val color = 0x123456
+ val red = (color and 0xff0000) shr 16
+ val green = (color and 0x00ff00) shr 8
+ val blue = (color and 0x0000ff) shr 0
+
+ Assert.assertEquals(0x12, red)
+ Assert.assertEquals(0x34, green)
+ Assert.assertEquals(0x56, blue)
+ }
+
+ @Test
+ fun testNewAssertions() {
+ class Assertion(private val target: T) {
+ infix fun isEqualTo(other: T) {
+ Assert.assertEquals(other, target)
+ }
+
+ infix fun isDifferentFrom(other: T) {
+ Assert.assertNotEquals(other, target)
+ }
+ }
+
+ val result = Assertion(5)
+
+ result isEqualTo 5
+
+ // The following two lines are expected to fail
+ // result isEqualTo 6
+ // result isDifferentFrom 5
+ }
+
+ @Test
+ fun testNewStringMethod() {
+ infix fun String.substringMatches(r: Regex) : List {
+ return r.findAll(this)
+ .map { it.value }
+ .toList()
+ }
+
+ val matches = "a bc def" substringMatches ".*? ".toRegex()
+ Assert.assertEquals(listOf("a ", "bc "), matches)
+ }
+}
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt
new file mode 100644
index 0000000000..7776eebd52
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt
@@ -0,0 +1,191 @@
+package com.baeldung.kotlin.kodein
+
+import com.github.salomonbrys.kodein.*
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+
+class KodeinUnitTest {
+
+ class InMemoryDao : Dao
+
+ @Test
+ fun whenSingletonBinding_thenSingleInstanceIsCreated() {
+ var created = false
+ val kodein = Kodein {
+ bind() with singleton {
+ created = true
+ MongoDao()
+ }
+ }
+
+ assertThat(created).isFalse()
+
+ val dao1: Dao = kodein.instance()
+
+ assertThat(created).isTrue()
+
+ val dao2: Dao = kodein.instance()
+
+ assertThat(dao1).isSameAs(dao2)
+ }
+
+ @Test
+ fun whenFactoryBinding_thenNewInstanceIsCreated() {
+ val kodein = Kodein {
+ bind() with singleton { MongoDao() }
+ bind() with factory { tag: String -> Service(instance(), tag) }
+ }
+ val service1: Service = kodein.with("myTag").instance()
+ val service2: Service = kodein.with("myTag").instance()
+
+ assertThat(service1).isNotSameAs(service2)
+ }
+
+ @Test
+ fun whenProviderBinding_thenNewInstanceIsCreated() {
+ val kodein = Kodein {
+ bind() with provider { MongoDao() }
+ }
+ val dao1: Dao = kodein.instance()
+ val dao2: Dao = kodein.instance()
+
+ assertThat(dao1).isNotSameAs(dao2)
+ }
+
+ @Test
+ fun whenTaggedBinding_thenMultipleInstancesOfSameTypeCanBeRegistered() {
+ val kodein = Kodein {
+ bind("dao1") with singleton { MongoDao() }
+ bind("dao2") with singleton { MongoDao() }
+ }
+ val dao1: Dao = kodein.instance("dao1")
+ val dao2: Dao = kodein.instance("dao2")
+
+ assertThat(dao1).isNotSameAs(dao2)
+ }
+
+ @Test
+ fun whenEagerSingletonBinding_thenCreationIsEager() {
+ var created = false
+ val kodein = Kodein {
+ bind() with eagerSingleton {
+ created = true
+ MongoDao()
+ }
+ }
+
+ assertThat(created).isTrue()
+ val dao1: Dao = kodein.instance()
+ val dao2: Dao = kodein.instance()
+
+ assertThat(dao1).isSameAs(dao2)
+ }
+
+ @Test
+ fun whenMultitonBinding_thenInstancesAreReused() {
+ val kodein = Kodein {
+ bind() with singleton { MongoDao() }
+ bind() with multiton { tag: String -> Service(instance(), tag) }
+ }
+ val service1: Service = kodein.with("myTag").instance()
+ val service2: Service = kodein.with("myTag").instance()
+
+ assertThat(service1).isSameAs(service2)
+ }
+
+ @Test
+ fun whenInstanceBinding_thenItIsReused() {
+ val dao = MongoDao()
+ val kodein = Kodein {
+ bind() with instance(dao)
+ }
+ val fromContainer: Dao = kodein.instance()
+
+ assertThat(dao).isSameAs(fromContainer)
+ }
+
+ @Test
+ fun whenConstantBinding_thenItIsAvailable() {
+ val kodein = Kodein {
+ constant("magic") with 42
+ }
+ val fromContainer: Int = kodein.instance("magic")
+
+ assertThat(fromContainer).isEqualTo(42)
+ }
+
+ @Test
+ fun whenUsingModules_thenTransitiveDependenciesAreSuccessfullyResolved() {
+ val jdbcModule = Kodein.Module {
+ bind() with singleton { JdbcDao() }
+ }
+ val kodein = Kodein {
+ import(jdbcModule)
+ bind() with singleton { Controller(instance()) }
+ bind() with singleton { Service(instance(), "myService") }
+ }
+
+ val dao: Dao = kodein.instance()
+ assertThat(dao).isInstanceOf(JdbcDao::class.java)
+ }
+
+ @Test
+ fun whenComposition_thenBeansAreReUsed() {
+ val persistenceContainer = Kodein {
+ bind() with singleton { MongoDao() }
+ }
+ val serviceContainer = Kodein {
+ extend(persistenceContainer)
+ bind() with singleton { Service(instance(), "myService") }
+ }
+ val fromPersistence: Dao = persistenceContainer.instance()
+ val fromService: Dao = serviceContainer.instance()
+
+ assertThat(fromPersistence).isSameAs(fromService)
+ }
+
+ @Test
+ fun whenOverriding_thenRightBeanIsUsed() {
+ val commonModule = Kodein.Module {
+ bind() with singleton { MongoDao() }
+ bind() with singleton { Service(instance(), "myService") }
+ }
+ val testContainer = Kodein {
+ import(commonModule)
+ bind(overrides = true) with singleton { InMemoryDao() }
+ }
+ val dao: Dao = testContainer.instance()
+
+ assertThat(dao).isInstanceOf(InMemoryDao::class.java)
+ }
+
+ @Test
+ fun whenMultiBinding_thenWorks() {
+ val kodein = Kodein {
+ bind() from setBinding()
+ bind().inSet() with singleton { MongoDao() }
+ bind().inSet() with singleton { JdbcDao() }
+ }
+ val daos: Set = kodein.instance()
+
+ assertThat(daos.map { it.javaClass as Class<*> }).containsOnly(MongoDao::class.java, JdbcDao::class.java)
+ }
+
+ @Test
+ fun whenInjector_thenWorks() {
+ class Controller2 {
+ private val injector = KodeinInjector()
+ val service: Service by injector.instance()
+ fun injectDependencies(kodein: Kodein) = injector.inject(kodein)
+ }
+
+ val kodein = Kodein {
+ bind() with singleton { MongoDao() }
+ bind() with singleton { Service(instance(), "myService") }
+ }
+ val controller = Controller2()
+ controller.injectDependencies(kodein)
+
+ assertThat(controller.service).isNotNull
+ }
+}
\ No newline at end of file
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/stdlib/RegexTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/stdlib/RegexTest.kt
new file mode 100644
index 0000000000..eeb587ee22
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/stdlib/RegexTest.kt
@@ -0,0 +1,128 @@
+package com.baeldung.kotlin.stdlib
+
+import org.junit.Test
+import java.beans.ExceptionListener
+import java.beans.XMLEncoder
+import java.io.*
+import java.lang.Exception
+import kotlin.test.*
+import kotlin.text.RegexOption.*
+
+class RegexTest {
+
+ @Test
+ fun whenRegexIsInstantiated_thenIsEqualToToRegexMethod() {
+ val pattern = """a([bc]+)d?\\"""
+
+ assertEquals(Regex.fromLiteral(pattern).pattern, pattern)
+ assertEquals(pattern, Regex(pattern).pattern)
+ assertEquals(pattern, pattern.toRegex().pattern)
+ }
+
+ @Test
+ fun whenRegexMatches_thenResultIsTrue() {
+ val regex = """a([bc]+)d?""".toRegex()
+
+ assertTrue(regex.containsMatchIn("xabcdy"))
+ assertTrue(regex.matches("abcd"))
+ assertFalse(regex matches "xabcdy")
+ }
+
+ @Test
+ fun givenCompletelyMatchingRegex_whenMatchResult_thenDestructuring() {
+ val regex = """a([bc]+)d?""".toRegex()
+
+ assertNull(regex.matchEntire("xabcdy"))
+
+ val matchResult = regex.matchEntire("abbccbbd")
+
+ assertNotNull(matchResult)
+ assertEquals(matchResult!!.value, matchResult.groupValues[0])
+ assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1))
+ assertEquals("bbccbb", matchResult.destructured.component1())
+ assertNull(matchResult.next())
+ }
+
+ @Test
+ fun givenPartiallyMatchingRegex_whenMatchResult_thenGroups() {
+ val regex = """a([bc]+)d?""".toRegex()
+ var matchResult = regex.find("abcb abbd")
+
+ assertNotNull(matchResult)
+ assertEquals(matchResult!!.value, matchResult.groupValues[0])
+ assertEquals("abcb", matchResult.value)
+ assertEquals(IntRange(0, 3), matchResult.range)
+ assertEquals(listOf("abcb", "bcb"), matchResult.groupValues)
+ assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1))
+
+ matchResult = matchResult.next()
+
+ assertNotNull(matchResult)
+ assertEquals("abbd", matchResult!!.value)
+ assertEquals("bb", matchResult.groupValues[1])
+
+ matchResult = matchResult.next()
+
+ assertNull(matchResult)
+ }
+
+ @Test
+ fun givenPartiallyMatchingRegex_whenMatchResult_thenDestructuring() {
+ val regex = """([\w\s]+) is (\d+) years old""".toRegex()
+ val matchResult = regex.find("Mickey Mouse is 95 years old")
+ val (name, age) = matchResult!!.destructured
+
+ assertEquals("Mickey Mouse", name)
+ assertEquals("95", age)
+ }
+
+ @Test
+ fun givenNonMatchingRegex_whenFindCalled_thenNull() {
+ val regex = """a([bc]+)d?""".toRegex()
+ val matchResult = regex.find("foo")
+
+ assertNull(matchResult)
+ }
+
+ @Test
+ fun givenNonMatchingRegex_whenFindAllCalled_thenEmptySet() {
+ val regex = """a([bc]+)d?""".toRegex()
+ val matchResults = regex.findAll("foo")
+
+ assertNotNull(matchResults)
+ assertTrue(matchResults.none())
+ }
+
+ @Test
+ fun whenReplace_thenReplacement() {
+ val regex = """(red|green|blue)""".toRegex()
+ val beautiful = "Roses are red, Violets are blue"
+ val grim = regex.replace(beautiful, "dark")
+ val shiny = regex.replaceFirst(beautiful, "rainbow")
+
+ assertEquals("Roses are dark, Violets are dark", grim)
+ assertEquals("Roses are rainbow, Violets are blue", shiny)
+ }
+
+ @Test
+ fun whenComplexReplace_thenReplacement() {
+ val regex = """(red|green|blue)""".toRegex()
+ val beautiful = "Roses are red, Violets are blue"
+ val reallyBeautiful = regex.replace(beautiful) {
+ matchResult -> matchResult.value.toUpperCase() + "!"
+ }
+
+ assertEquals("Roses are RED!, Violets are BLUE!", reallyBeautiful)
+ }
+
+ @Test
+ fun whenSplit_thenList() {
+ val regex = """\W+""".toRegex()
+ val beautiful = "Roses are red, Violets are blue"
+
+ assertEquals(listOf("Roses", "are", "red", "Violets", "are", "blue"), regex.split(beautiful))
+ assertEquals(listOf("Roses", "are", "red", "Violets are blue"), regex.split(beautiful, 4))
+ assertEquals(regex.toPattern().split(beautiful).asList(), regex.split(beautiful))
+ }
+
+}
\ No newline at end of file
diff --git a/ethereumj/pom.xml b/ethereumj/pom.xml
index c9f5924d7a..9676106e38 100644
--- a/ethereumj/pom.xml
+++ b/ethereumj/pom.xml
@@ -1,6 +1,5 @@
-
+4.0.0com.baeldung.ethereumjethereumj
@@ -8,16 +7,11 @@
1.0.0ethereumj
-
- UTF-8
- 1.8
- 8.5.4
-
-
- org.springframework.boot
- spring-boot-starter-parent
- 1.5.6.RELEASE
+ parent-boot-5
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-5
@@ -38,14 +32,12 @@
org.springframework.bootspring-boot-starter-tomcat
-
org.springframework.bootspring-boot-starter-test
- 1.5.6.RELEASEtest
@@ -107,4 +99,11 @@
+
+
+ UTF-8
+ 1.8
+ 8.5.4
+
+
\ No newline at end of file
diff --git a/google-cloud/README.md b/google-cloud/README.md
new file mode 100644
index 0000000000..6022796a0e
--- /dev/null
+++ b/google-cloud/README.md
@@ -0,0 +1,16 @@
+## Google Cloud Tutorial Project
+
+### Relevant Article:
+- [Intro to Google Cloud Storage With Java](http://www.baeldung.com/intro-to-google-cloud-storage-with-java/)
+
+### Overview
+This Maven project contains the Java code for the article linked above.
+
+### Package Organization
+Java classes for the intro tutorial are in the org.baeldung.google.cloud package. Please note that Google Cloud requires
+a user account and credentials, as explained in the tutorial.
+
+
+### Running the tests
+
+```
diff --git a/google-cloud/pom.xml b/google-cloud/pom.xml
new file mode 100644
index 0000000000..0f1eff36f8
--- /dev/null
+++ b/google-cloud/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+ google-cloud
+ 0.1-SNAPSHOT
+ jar
+ google-cloud
+ Google Cloud Tutorials
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ com.google.cloud
+ google-cloud-storage
+ 1.16.0
+
+
+ org.projectlombok
+ lombok
+
+ ${lombok.version}
+ provided
+
+
+
+
+ 1.16.18
+ 1.8
+ UTF-8
+
+
+
diff --git a/google-cloud/src/main/java/com/baeldung/google/cloud/storage/GoogleCloudStorage.java b/google-cloud/src/main/java/com/baeldung/google/cloud/storage/GoogleCloudStorage.java
new file mode 100644
index 0000000000..a69171f1db
--- /dev/null
+++ b/google-cloud/src/main/java/com/baeldung/google/cloud/storage/GoogleCloudStorage.java
@@ -0,0 +1,105 @@
+package com.baeldung.google.cloud.storage;
+
+import com.google.api.gax.paging.Page;
+import com.google.auth.Credentials;
+import com.google.auth.oauth2.GoogleCredentials;
+import com.google.cloud.storage.*;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * Simple class for creating, reading and modifying text blobs on Google Cloud
+ */
+@Slf4j
+public class GoogleCloudStorage {
+
+ private Storage storage;
+ private Bucket bucket;
+
+ public static void main(String[] args) throws Exception {
+
+ // Use this variation to read the Google authorization JSON from the resources directory with a path
+ // and a project name.
+ GoogleCloudStorage googleCloudStorage =
+ new GoogleCloudStorage("google-cloud/src/main/resources/google_auth.json", "baeldung-cloud-tutorial");
+
+ // Bucket require globally unique names, so you'll probably need to change this
+ Bucket bucket = googleCloudStorage.getBucket("baeldung-1-bucket");
+
+ // Save a simple string
+ BlobId blobId = googleCloudStorage.saveString("my-first-blob", "Hi there!", bucket);
+
+ // Get it by blob id this time
+ String value = googleCloudStorage.getString(blobId);
+
+ log.info("Read data: {}", value);
+
+ googleCloudStorage.updateString(blobId, "Bye now!");
+
+ // Get the string by blob name
+ value = googleCloudStorage.getString("my-first-blob");
+
+ log.info("Read modified data: {}", value);
+
+
+ }
+
+
+ // Use path and project name
+ private GoogleCloudStorage(String pathToConfig, String projectId) throws IOException {
+ Credentials credentials = GoogleCredentials.fromStream(new FileInputStream(pathToConfig));
+ storage = StorageOptions.newBuilder().setCredentials(credentials).setProjectId(projectId).build().getService();
+ }
+
+ // Check for bucket existence and create if needed.
+ private Bucket getBucket(String bucketName) {
+ bucket = storage.get(bucketName);
+ if (bucket == null) {
+ System.out.println("Creating new bucket.");
+ bucket = storage.create(BucketInfo.of(bucketName));
+ }
+ return bucket;
+ }
+
+ // Save a string to a blob
+ private BlobId saveString(String blobName, String value, Bucket bucket) {
+ byte[] bytes = value.getBytes(UTF_8);
+ Blob blob = bucket.create(blobName, bytes);
+ return blob.getBlobId();
+ }
+
+
+ // get a blob by id
+ private String getString(BlobId blobId) {
+ Blob blob = storage.get(blobId);
+ return new String(blob.getContent());
+ }
+
+
+ // get a blob by name
+ private String getString(String name) {
+ Page blobs = bucket.list();
+ for (Blob blob: blobs.getValues()) {
+ if (name.equals(blob.getName())) {
+ return new String(blob.getContent());
+ }
+ }
+ return "Blob not found";
+ }
+
+ // Update a blob
+ private void updateString(BlobId blobId, String newString) throws IOException {
+ Blob blob = storage.get(blobId);
+ if (blob != null) {
+ WritableByteChannel channel = blob.writer();
+ channel.write(ByteBuffer.wrap(newString.getBytes(UTF_8)));
+ channel.close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/gradle/build.gradle b/gradle/build.gradle
index dcc592a2b4..2e5d984fba 100644
--- a/gradle/build.gradle
+++ b/gradle/build.gradle
@@ -33,3 +33,60 @@ task execSecondTest {
}
println 'This will be executed during the configuration phase as well.'
}
+
+task welcome {
+ doLast {
+ println 'Welcome on the Baeldung!'
+ }
+}
+
+task welcomeWithGroup {
+ group 'Sample category'
+ doLast {
+ println 'Welcome on the Baeldung!'
+ }
+}
+
+task welcomeWithGroupAndDescription {
+ group 'Sample category'
+ description 'Tasks which shows welcome message'
+ doLast {
+ println 'Welcome on the Baeldung!'
+ }
+}
+
+class PrintToolVersionTask extends DefaultTask {
+ String tool
+
+ @TaskAction
+ void printToolVersion() {
+ switch (tool) {
+ case 'java':
+ println System.getProperty("java.version")
+ break
+ case 'groovy':
+ println GroovySystem.version
+ break
+ default:
+ throw new IllegalArgumentException("Unknown tool")
+ }
+ }
+}
+
+task printJavaVersion(type : PrintToolVersionTask) {
+ tool 'java'
+}
+
+task printGroovyVersion(type : PrintToolVersionTask) {
+ tool 'groovy'
+}
+
+import com.baeldung.PrintToolVersionBuildSrcTask
+
+task printJavaVersionBuildSrc(type : PrintToolVersionBuildSrcTask) {
+ tool 'java'
+}
+
+task printGroovyVersionBuildSrc(type : PrintToolVersionBuildSrcTask) {
+ tool 'groovy'
+}
\ No newline at end of file
diff --git a/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy b/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy
new file mode 100644
index 0000000000..0fbd71db56
--- /dev/null
+++ b/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy
@@ -0,0 +1,22 @@
+package com.baeldung
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.TaskAction
+
+class PrintToolVersionBuildSrcTask extends DefaultTask {
+ String tool
+
+ @TaskAction
+ void printToolVersion() {
+ switch (tool) {
+ case 'java':
+ println System.getProperty("java.version")
+ break
+ case 'groovy':
+ println GroovySystem.version
+ break
+ default:
+ throw new IllegalArgumentException("Unknown tool")
+ }
+ }
+}
\ No newline at end of file
diff --git a/guava/README.md b/guava/README.md
index 7ab70cb01f..924187867e 100644
--- a/guava/README.md
+++ b/guava/README.md
@@ -19,6 +19,7 @@
- [Guide to Guava’s Ordering](http://www.baeldung.com/guava-ordering)
- [Guide to Guava’s PreConditions](http://www.baeldung.com/guava-preconditions)
- [Introduction to Guava CacheLoader](http://www.baeldung.com/guava-cacheloader)
+- [Introduction to Guava Memoizer](http://www.baeldung.com/guava-memoizer)
- [Guide to Guava’s EventBus](http://www.baeldung.com/guava-eventbus)
- [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap)
- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset)
diff --git a/guava/pom.xml b/guava/pom.xml
index 4afb4da301..aa162b7d1b 100644
--- a/guava/pom.xml
+++ b/guava/pom.xml
@@ -43,6 +43,14 @@
${assertj.version}test
+
+
+ org.hamcrest
+ java-hamcrest
+ 2.0.0.0
+ test
+
+
diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestFileUnitTest.java b/guava/src/test/java/org/baeldung/hamcrest/HamcrestFileUnitTest.java
new file mode 100644
index 0000000000..652e315651
--- /dev/null
+++ b/guava/src/test/java/org/baeldung/hamcrest/HamcrestFileUnitTest.java
@@ -0,0 +1,64 @@
+package org.baeldung.hamcrest;
+
+import static org.hamcrest.core.StringContains.containsString;
+import static org.hamcrest.io.FileMatchers.aFileNamed;
+import static org.hamcrest.io.FileMatchers.aFileWithAbsolutePath;
+import static org.hamcrest.io.FileMatchers.aFileWithCanonicalPath;
+import static org.hamcrest.io.FileMatchers.aFileWithSize;
+import static org.hamcrest.io.FileMatchers.aReadableFile;
+import static org.hamcrest.io.FileMatchers.aWritableFile;
+import static org.hamcrest.io.FileMatchers.anExistingDirectory;
+import static org.hamcrest.io.FileMatchers.anExistingFile;
+import static org.hamcrest.io.FileMatchers.anExistingFileOrDirectory;
+import static org.hamcrest.number.OrderingComparison.greaterThan;
+import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+
+import org.junit.Test;
+
+public class HamcrestFileUnitTest {
+
+ @Test
+ public final void whenVerifyingFileName_thenCorrect() {
+ File file = new File("src/test/resources/test1.in");
+
+ assertThat(file, aFileNamed(equalToIgnoringCase("test1.in")));
+ }
+
+ @Test
+ public final void whenVerifyingFileOrDirExist_thenCorrect() {
+ File file = new File("src/test/resources/test1.in");
+ File dir = new File("src/test/resources");
+
+ assertThat(file, anExistingFile());
+ assertThat(dir, anExistingDirectory());
+ assertThat(file, anExistingFileOrDirectory());
+ assertThat(dir, anExistingFileOrDirectory());
+ }
+
+ @Test
+ public final void whenVerifyingFileIsReadableAndWritable_thenCorrect() {
+ File file = new File("src/test/resources/test1.in");
+
+ assertThat(file, aReadableFile());
+ assertThat(file, aWritableFile());
+ }
+
+ @Test
+ public final void whenVerifyingFileSize_thenCorrect() {
+ File file = new File("src/test/resources/test1.in");
+
+ assertThat(file, aFileWithSize(11));
+ assertThat(file, aFileWithSize(greaterThan(1L)));;
+ }
+
+ @Test
+ public final void whenVerifyingFilePath_thenCorrect() {
+ File file = new File("src/test/resources/test1.in");
+
+ assertThat(file, aFileWithCanonicalPath(containsString("src/test/resources")));
+ assertThat(file, aFileWithAbsolutePath(containsString("src/test/resources")));
+ }
+}
diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestTextUnitTest.java b/guava/src/test/java/org/baeldung/hamcrest/HamcrestTextUnitTest.java
new file mode 100644
index 0000000000..e336b1bba3
--- /dev/null
+++ b/guava/src/test/java/org/baeldung/hamcrest/HamcrestTextUnitTest.java
@@ -0,0 +1,97 @@
+package org.baeldung.hamcrest;
+
+import static org.hamcrest.core.StringContains.containsString;
+import static org.hamcrest.core.StringContains.containsStringIgnoringCase;
+import static org.hamcrest.core.StringEndsWith.endsWith;
+import static org.hamcrest.core.StringEndsWith.endsWithIgnoringCase;
+import static org.hamcrest.core.StringStartsWith.startsWith;
+import static org.hamcrest.core.StringStartsWith.startsWithIgnoringCase;
+import static org.hamcrest.text.IsBlankString.blankOrNullString;
+import static org.hamcrest.text.IsBlankString.blankString;
+import static org.hamcrest.text.IsEmptyString.emptyOrNullString;
+import static org.hamcrest.text.IsEmptyString.emptyString;
+import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
+import static org.hamcrest.text.IsEqualIgnoringWhiteSpace.equalToIgnoringWhiteSpace;
+import static org.hamcrest.text.MatchesPattern.matchesPattern;
+import static org.hamcrest.text.StringContainsInOrder.stringContainsInOrder;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class HamcrestTextUnitTest {
+
+ @Test
+ public final void whenTwoStringsAreEqual_thenCorrect() {
+ String first = "hello";
+ String second = "Hello";
+
+ assertThat(first, equalToIgnoringCase(second));
+ }
+
+ @Test
+ public final void whenTwoStringsAreEqualWithWhiteSpace_thenCorrect() {
+ String first = "hello";
+ String second = " Hello ";
+
+ assertThat(first, equalToIgnoringWhiteSpace(second));
+ }
+
+ @Test
+ public final void whenStringIsBlank_thenCorrect() {
+ String first = " ";
+ String second = null;
+
+ assertThat(first, blankString());
+ assertThat(first, blankOrNullString());
+ assertThat(second, blankOrNullString());
+ }
+
+ @Test
+ public final void whenStringIsEmpty_thenCorrect() {
+ String first = "";
+ String second = null;
+
+ assertThat(first, emptyString());
+ assertThat(first, emptyOrNullString());
+ assertThat(second, emptyOrNullString());
+ }
+
+ @Test
+ public final void whenStringMatchPattern_thenCorrect() {
+ String first = "hello";
+
+ assertThat(first, matchesPattern("[a-z]+"));
+ }
+
+ @Test
+ public final void whenVerifyStringContains_thenCorrect() {
+ String first = "hello";
+
+ assertThat(first, containsString("lo"));
+ assertThat(first, containsStringIgnoringCase("EL"));
+ }
+
+ @Test
+ public final void whenVerifyStringContainsInOrder_thenCorrect() {
+ String first = "hello";
+
+ assertThat(first, stringContainsInOrder("e","l","o"));
+ }
+
+ @Test
+ public final void whenVerifyStringStartsWith_thenCorrect() {
+ String first = "hello";
+
+ assertThat(first, startsWith("he"));
+ assertThat(first, startsWithIgnoringCase("HEL"));
+ }
+
+ @Test
+ public final void whenVerifyStringEndsWith_thenCorrect() {
+ String first = "hello";
+
+ assertThat(first, endsWith("lo"));
+ assertThat(first, endsWithIgnoringCase("LO"));
+ }
+
+}
diff --git a/guest/core-java/pom.xml b/guest/core-java/pom.xml
index 222716386b..eda3846c1f 100644
--- a/guest/core-java/pom.xml
+++ b/guest/core-java/pom.xml
@@ -16,6 +16,24 @@
log4j-core${log4j2.version}
+
+ org.hamcrest
+ hamcrest-core
+ ${org.hamcrest.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-library
+ ${org.hamcrest.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-all
+ ${org.hamcrest.version}
+ test
+
@@ -32,5 +50,6 @@
2.8.2
+ 1.3
\ No newline at end of file
diff --git a/guest/core-java/src/main/java/com/stackify/stream/Employee.java b/guest/core-java/src/main/java/com/stackify/stream/Employee.java
new file mode 100644
index 0000000000..005990c863
--- /dev/null
+++ b/guest/core-java/src/main/java/com/stackify/stream/Employee.java
@@ -0,0 +1,46 @@
+package com.stackify.stream;
+
+public class Employee {
+ private Integer id;
+ private String name;
+ private Double salary;
+
+ public Employee(Integer id, String name, Double salary) {
+ this.id = id;
+ this.name = name;
+ this.salary = salary;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Double getSalary() {
+ return salary;
+ }
+
+ public void setSalary(Double salary) {
+ this.salary = salary;
+ }
+
+ public void salaryIncrement(Double percentage) {
+ Double newSalary = salary + percentage * salary / 100;
+ setSalary(newSalary);
+ }
+
+ public String toString() {
+ return "Id: " + id + " Name:" + name + " Price:" + salary;
+ }
+}
diff --git a/guest/core-java/src/main/java/com/stackify/stream/EmployeeRepository.java b/guest/core-java/src/main/java/com/stackify/stream/EmployeeRepository.java
new file mode 100644
index 0000000000..223fee5e26
--- /dev/null
+++ b/guest/core-java/src/main/java/com/stackify/stream/EmployeeRepository.java
@@ -0,0 +1,21 @@
+package com.stackify.stream;
+
+import java.util.List;
+
+public class EmployeeRepository {
+ private List empList;
+
+ public EmployeeRepository(List empList) {
+ this.empList = empList;
+
+ }
+ public Employee findById(Integer id) {
+ for (Employee emp : empList) {
+ if (emp.getId() == id) {
+ return emp;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/guest/core-java/src/test/java/com/stackify/stream/EmployeeTest.java b/guest/core-java/src/test/java/com/stackify/stream/EmployeeTest.java
new file mode 100644
index 0000000000..cf988d035a
--- /dev/null
+++ b/guest/core-java/src/test/java/com/stackify/stream/EmployeeTest.java
@@ -0,0 +1,455 @@
+package com.stackify.stream;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.DoubleSummaryStatistics;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+import java.util.Set;
+import java.util.Vector;
+import java.util.function.BinaryOperator;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.After;
+import org.junit.Test;
+
+public class EmployeeTest {
+ private String fileName = "src/test/resources/test.txt";
+
+ private static Employee[] arrayOfEmps = {
+ new Employee(1, "Jeff Bezos", 100000.0),
+ new Employee(2, "Bill Gates", 200000.0),
+ new Employee(3, "Mark Zuckerberg", 300000.0)
+ };
+
+ private static List empList = Arrays.asList(arrayOfEmps);
+ private static EmployeeRepository employeeRepository = new EmployeeRepository(empList);
+
+ @After
+ public void cleanup() throws IOException {
+ Files.deleteIfExists(Paths.get(fileName));
+ }
+
+ @Test
+ public void whenGetStreamFromList_ObtainStream() {
+ assert(empList.stream() instanceof Stream>);
+ }
+
+ @Test
+ public void whenGetStreamFromArray_ObtainStream() {
+ assert(Stream.of(arrayOfEmps) instanceof Stream>);
+ }
+
+ @Test
+ public void whenGetStreamFromElements_ObtainStream() {
+ assert(Stream.of(arrayOfEmps[0], arrayOfEmps[1], arrayOfEmps[2]) instanceof Stream>);
+ }
+
+ @Test
+ public void whenBuildStreamFromElements_ObtainStream() {
+ Stream.Builder empStreamBuilder = Stream.builder();
+
+ empStreamBuilder.accept(arrayOfEmps[0]);
+ empStreamBuilder.accept(arrayOfEmps[1]);
+ empStreamBuilder.accept(arrayOfEmps[2]);
+
+ Stream empStream = empStreamBuilder.build();
+
+ assert(empStream instanceof Stream>);
+ }
+
+ @Test
+ public void whenIncrementSalaryForEachEmployee_thenApplyNewSalary() {
+ Employee[] arrayOfEmps = {
+ new Employee(1, "Jeff Bezos", 100000.0),
+ new Employee(2, "Bill Gates", 200000.0),
+ new Employee(3, "Mark Zuckerberg", 300000.0)
+ };
+
+ List empList = Arrays.asList(arrayOfEmps);
+
+ empList.stream().forEach(e -> e.salaryIncrement(10.0));
+
+ assertThat(empList, contains(
+ hasProperty("salary", equalTo(110000.0)),
+ hasProperty("salary", equalTo(220000.0)),
+ hasProperty("salary", equalTo(330000.0))
+ ));
+ }
+
+ @Test
+ public void whenIncrementSalaryUsingPeek_thenApplyNewSalary() {
+ Employee[] arrayOfEmps = {
+ new Employee(1, "Jeff Bezos", 100000.0),
+ new Employee(2, "Bill Gates", 200000.0),
+ new Employee(3, "Mark Zuckerberg", 300000.0)
+ };
+
+ List empList = Arrays.asList(arrayOfEmps);
+
+ empList.stream()
+ .peek(e -> e.salaryIncrement(10.0))
+ .peek(System.out::println)
+ .collect(Collectors.toList());
+
+ assertThat(empList, contains(
+ hasProperty("salary", equalTo(110000.0)),
+ hasProperty("salary", equalTo(220000.0)),
+ hasProperty("salary", equalTo(330000.0))
+ ));
+ }
+
+ @Test
+ public void whenMapIdToEmployees_thenGetEmployeeStream() {
+ Integer[] empIds = { 1, 2, 3 };
+
+ List employees = Stream.of(empIds)
+ .map(employeeRepository::findById)
+ .collect(Collectors.toList());
+
+ assertEquals(employees.size(), empIds.length);
+ }
+
+ @Test
+ public void whenFlatMapEmployeeNames_thenGetNameStream() {
+ List> namesNested = Arrays.asList(
+ Arrays.asList("Jeff", "Bezos"),
+ Arrays.asList("Bill", "Gates"),
+ Arrays.asList("Mark", "Zuckerberg"));
+
+ List namesFlatStream = namesNested.stream()
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+
+ assertEquals(namesFlatStream.size(), namesNested.size() * 2);
+ }
+
+ @Test
+ public void whenFilterEmployees_thenGetFilteredStream() {
+ Integer[] empIds = { 1, 2, 3, 4 };
+
+ List employees = Stream.of(empIds)
+ .map(employeeRepository::findById)
+ .filter(e -> e != null)
+ .filter(e -> e.getSalary() > 200000)
+ .collect(Collectors.toList());
+
+ assertEquals(Arrays.asList(arrayOfEmps[2]), employees);
+ }
+
+ @Test
+ public void whenFindFirst_thenGetFirstEmployeeInStream() {
+ Integer[] empIds = { 1, 2, 3, 4 };
+
+ Employee employee = Stream.of(empIds)
+ .map(employeeRepository::findById)
+ .filter(e -> e != null)
+ .filter(e -> e.getSalary() > 100000)
+ .findFirst()
+ .orElse(null);
+
+ assertEquals(employee.getSalary(), new Double(200000));
+ }
+
+ @Test
+ public void whenCollectStreamToList_thenGetList() {
+ List employees = empList.stream().collect(Collectors.toList());
+
+ assertEquals(empList, employees);
+ }
+
+ @Test
+ public void whenStreamToArray_thenGetArray() {
+ Employee[] employees = empList.stream().toArray(Employee[]::new);
+
+ assertThat(empList.toArray(), equalTo(employees));
+ }
+
+ @Test
+ public void whenStreamCount_thenGetElementCount() {
+ Long empCount = empList.stream()
+ .filter(e -> e.getSalary() > 200000)
+ .count();
+
+ assertEquals(empCount, new Long(1));
+ }
+
+ @Test
+ public void whenLimitInfiniteStream_thenGetFiniteElements() {
+ Stream infiniteStream = Stream.iterate(2, i -> i * 2);
+
+ List collect = infiniteStream
+ .skip(3)
+ .limit(5)
+ .collect(Collectors.toList());
+
+ assertEquals(collect, Arrays.asList(16, 32, 64, 128, 256));
+ }
+
+ @Test
+ public void whenSortStream_thenGetSortedStream() {
+ List employees = empList.stream()
+ .sorted((e1, e2) -> e1.getName().compareTo(e2.getName()))
+ .collect(Collectors.toList());
+
+ assertEquals(employees.get(0).getName(), "Bill Gates");
+ assertEquals(employees.get(1).getName(), "Jeff Bezos");
+ assertEquals(employees.get(2).getName(), "Mark Zuckerberg");
+ }
+
+
+ @Test
+ public void whenFindMin_thenGetMinElementFromStream() {
+ Employee firstEmp = empList.stream()
+ .min((e1, e2) -> e1.getId() - e2.getId())
+ .orElseThrow(NoSuchElementException::new);
+
+ assertEquals(firstEmp.getId(), new Integer(1));
+ }
+
+ @Test
+ public void whenFindMax_thenGetMaxElementFromStream() {
+ Employee maxSalEmp = empList.stream()
+ .max(Comparator.comparing(Employee::getSalary))
+ .orElseThrow(NoSuchElementException::new);
+
+ assertEquals(maxSalEmp.getSalary(), new Double(300000.0));
+ }
+
+ @Test
+ public void whenApplyDistinct_thenRemoveDuplicatesFromStream() {
+ List intList = Arrays.asList(2, 5, 3, 2, 4, 3);
+ List distinctIntList = intList.stream().distinct().collect(Collectors.toList());
+
+ assertEquals(distinctIntList, Arrays.asList(2, 5, 3, 4));
+ }
+
+ @Test
+ public void whenApplyMatch_thenReturnBoolean() {
+ List intList = Arrays.asList(2, 4, 5, 6, 8);
+
+ boolean allEven = intList.stream().allMatch(i -> i % 2 == 0);
+ boolean oneEven = intList.stream().anyMatch(i -> i % 2 == 0);
+ boolean noneMultipleOfThree = intList.stream().noneMatch(i -> i % 3 == 0);
+
+ assertEquals(allEven, false);
+ assertEquals(oneEven, true);
+ assertEquals(noneMultipleOfThree, false);
+ }
+
+ @Test
+ public void whenFindMaxOnIntStream_thenGetMaxInteger() {
+ Integer latestEmpId = empList.stream()
+ .mapToInt(Employee::getId)
+ .max()
+ .orElseThrow(NoSuchElementException::new);
+
+ assertEquals(latestEmpId, new Integer(3));
+ }
+
+ @Test
+ public void whenApplySumOnIntStream_thenGetSum() {
+ Double avgSal = empList.stream()
+ .mapToDouble(Employee::getSalary)
+ .average()
+ .orElseThrow(NoSuchElementException::new);
+
+ assertEquals(avgSal, new Double(200000));
+ }
+
+ @Test
+ public void whenApplyReduceOnStream_thenGetValue() {
+ Double sumSal = empList.stream()
+ .map(Employee::getSalary)
+ .reduce(0.0, Double::sum);
+
+ assertEquals(sumSal, new Double(600000));
+ }
+
+ @Test
+ public void whenCollectByJoining_thenGetJoinedString() {
+ String empNames = empList.stream()
+ .map(Employee::getName)
+ .collect(Collectors.joining(", "))
+ .toString();
+
+ assertEquals(empNames, "Jeff Bezos, Bill Gates, Mark Zuckerberg");
+ }
+
+ @Test
+ public void whenCollectBySet_thenGetSet() {
+ Set empNames = empList.stream()
+ .map(Employee::getName)
+ .collect(Collectors.toSet());
+
+ assertEquals(empNames.size(), 3);
+ }
+
+ @Test
+ public void whenToVectorCollection_thenGetVector() {
+ Vector empNames = empList.stream()
+ .map(Employee::getName)
+ .collect(Collectors.toCollection(Vector::new));
+
+ assertEquals(empNames.size(), 3);
+ }
+
+ @Test
+ public void whenApplySummarizing_thenGetBasicStats() {
+ DoubleSummaryStatistics stats = empList.stream()
+ .collect(Collectors.summarizingDouble(Employee::getSalary));
+
+ assertEquals(stats.getCount(), 3);
+ assertEquals(stats.getSum(), 600000.0, 0);
+ assertEquals(stats.getMin(), 100000.0, 0);
+ assertEquals(stats.getMax(), 300000.0, 0);
+ assertEquals(stats.getAverage(), 200000.0, 0);
+ }
+
+ @Test
+ public void whenApplySummaryStatistics_thenGetBasicStats() {
+ DoubleSummaryStatistics stats = empList.stream()
+ .mapToDouble(Employee::getSalary)
+ .summaryStatistics();
+
+ assertEquals(stats.getCount(), 3);
+ assertEquals(stats.getSum(), 600000.0, 0);
+ assertEquals(stats.getMin(), 100000.0, 0);
+ assertEquals(stats.getMax(), 300000.0, 0);
+ assertEquals(stats.getAverage(), 200000.0, 0);
+ }
+
+ @Test
+ public void whenStreamPartition_thenGetMap() {
+ List intList = Arrays.asList(2, 4, 5, 6, 8);
+ Map> isEven = intList.stream().collect(
+ Collectors.partitioningBy(i -> i % 2 == 0));
+
+ assertEquals(isEven.get(true).size(), 4);
+ assertEquals(isEven.get(false).size(), 1);
+ }
+
+ @Test
+ public void whenStreamGroupingBy_thenGetMap() {
+ Map> groupByAlphabet = empList.stream().collect(
+ Collectors.groupingBy(e -> new Character(e.getName().charAt(0))));
+
+ assertEquals(groupByAlphabet.get('B').get(0).getName(), "Bill Gates");
+ assertEquals(groupByAlphabet.get('J').get(0).getName(), "Jeff Bezos");
+ assertEquals(groupByAlphabet.get('M').get(0).getName(), "Mark Zuckerberg");
+ }
+
+ @Test
+ public void whenStreamMapping_thenGetMap() {
+ Map> idGroupedByAlphabet = empList.stream().collect(
+ Collectors.groupingBy(e -> new Character(e.getName().charAt(0)),
+ Collectors.mapping(Employee::getId, Collectors.toList())));
+
+ assertEquals(idGroupedByAlphabet.get('B').get(0), new Integer(2));
+ assertEquals(idGroupedByAlphabet.get('J').get(0), new Integer(1));
+ assertEquals(idGroupedByAlphabet.get('M').get(0), new Integer(3));
+ }
+
+ @Test
+ public void whenStreamReducing_thenGetValue() {
+ Double percentage = 10.0;
+ Double salIncrOverhead = empList.stream().collect(Collectors.reducing(
+ 0.0, e -> e.getSalary() * percentage / 100, (s1, s2) -> s1 + s2));
+
+ assertEquals(salIncrOverhead, 60000.0, 0);
+ }
+
+ @Test
+ public void whenStreamGroupingAndReducing_thenGetMap() {
+ Comparator byNameLength = Comparator.comparing(Employee::getName);
+
+ Map> longestNameByAlphabet = empList.stream().collect(
+ Collectors.groupingBy(e -> new Character(e.getName().charAt(0)),
+ Collectors.reducing(BinaryOperator.maxBy(byNameLength))));
+
+ assertEquals(longestNameByAlphabet.get('B').get().getName(), "Bill Gates");
+ assertEquals(longestNameByAlphabet.get('J').get().getName(), "Jeff Bezos");
+ assertEquals(longestNameByAlphabet.get('M').get().getName(), "Mark Zuckerberg");
+ }
+
+ @Test
+ public void whenParallelStream_thenPerformOperationsInParallel() {
+ Employee[] arrayOfEmps = {
+ new Employee(1, "Jeff Bezos", 100000.0),
+ new Employee(2, "Bill Gates", 200000.0),
+ new Employee(3, "Mark Zuckerberg", 300000.0)
+ };
+
+ List empList = Arrays.asList(arrayOfEmps);
+
+ empList.stream().parallel().forEach(e -> e.salaryIncrement(10.0));
+
+ assertThat(empList, contains(
+ hasProperty("salary", equalTo(110000.0)),
+ hasProperty("salary", equalTo(220000.0)),
+ hasProperty("salary", equalTo(330000.0))
+ ));
+ }
+
+ @Test
+ public void whenGenerateStream_thenGetInfiniteStream() {
+ Stream.generate(Math::random)
+ .limit(5)
+ .forEach(System.out::println);
+ }
+
+ @Test
+ public void whenIterateStream_thenGetInfiniteStream() {
+ Stream evenNumStream = Stream.iterate(2, i -> i * 2);
+
+ List collect = evenNumStream
+ .limit(5)
+ .collect(Collectors.toList());
+
+ assertEquals(collect, Arrays.asList(2, 4, 8, 16, 32));
+ }
+
+ @Test
+ public void whenStreamToFile_thenGetFile() throws IOException {
+ String[] words = {
+ "hello",
+ "refer",
+ "world",
+ "level"
+ };
+
+ try (PrintWriter pw = new PrintWriter(
+ Files.newBufferedWriter(Paths.get(fileName)))) {
+ Stream.of(words).forEach(pw::println);
+ }
+ }
+
+ private List getPalindrome(Stream stream, int length) {
+ return stream.filter(s -> s.length() == length)
+ .filter(s -> s.compareToIgnoreCase(
+ new StringBuilder(s).reverse().toString()) == 0)
+ .collect(Collectors.toList());
+ }
+
+ @Test
+ public void whenFileToStream_thenGetStream() throws IOException {
+ whenStreamToFile_thenGetFile();
+
+ List str = getPalindrome(Files.lines(Paths.get(fileName)), 5);
+ assertThat(str, contains("refer", "level"));
+ }
+}
diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties b/guest/core-java/src/test/resources/.keep
similarity index 100%
rename from spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties
rename to guest/core-java/src/test/resources/.keep
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java b/hibernate5/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java
index c8b3397b09..506e674984 100644
--- a/hibernate5/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java
@@ -11,31 +11,49 @@ public class PersonNameConverter implements AttributeConverter= 2 && pieces[1] != null && !pieces[1].isEmpty()) {
+ personName.setName(pieces[1]);
+ }
+ } else {
+ personName.setName(firstPiece);
+ }
return personName;
}
diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterTest.java
index aec2311294..204d8775ff 100644
--- a/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterTest.java
+++ b/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterTest.java
@@ -71,4 +71,130 @@ public class PersonNameConverterTest {
.getSurname(), surname);
}
+ @Test
+ public void givenPersonNameNull_WhenSaving_ThenNullStored() {
+ final String name = null;
+ final String surname = null;
+
+ PersonName personName = new PersonName();
+ personName.setName(name);
+ personName.setSurname(surname);
+
+ Person person = new Person();
+ person.setPersonName(personName);
+
+ Long id = (Long) session.save(person);
+
+ session.flush();
+ session.clear();
+
+ String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id")
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals("", dbPersonName);
+
+ Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class)
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals(dbPerson.getPersonName(), null);
+ }
+
+ @Test
+ public void givenPersonNameWithoutName_WhenSaving_ThenNotNameStored() {
+ final String name = null;
+ final String surname = "surname";
+
+ PersonName personName = new PersonName();
+ personName.setName(name);
+ personName.setSurname(surname);
+
+ Person person = new Person();
+ person.setPersonName(personName);
+
+ Long id = (Long) session.save(person);
+
+ session.flush();
+ session.clear();
+
+ String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id")
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals("surname, ", dbPersonName);
+
+ Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class)
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals(dbPerson.getPersonName()
+ .getName(), name);
+ assertEquals(dbPerson.getPersonName()
+ .getSurname(), surname);
+ }
+
+ @Test
+ public void givenPersonNameWithoutSurName_WhenSaving_ThenNotSurNameStored() {
+ final String name = "name";
+ final String surname = null;
+
+ PersonName personName = new PersonName();
+ personName.setName(name);
+ personName.setSurname(surname);
+
+ Person person = new Person();
+ person.setPersonName(personName);
+
+ Long id = (Long) session.save(person);
+
+ session.flush();
+ session.clear();
+
+ String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id")
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals("name", dbPersonName);
+
+ Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class)
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals(dbPerson.getPersonName()
+ .getName(), name);
+ assertEquals(dbPerson.getPersonName()
+ .getSurname(), surname);
+ }
+
+ @Test
+ public void givenPersonNameEmptyFields_WhenSaving_ThenFielsNotStored() {
+ final String name = "";
+ final String surname = "";
+
+ PersonName personName = new PersonName();
+ personName.setName(name);
+ personName.setSurname(surname);
+
+ Person person = new Person();
+ person.setPersonName(personName);
+
+ Long id = (Long) session.save(person);
+
+ session.flush();
+ session.clear();
+
+ String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id")
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals("", dbPersonName);
+
+ Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class)
+ .setParameter("id", id)
+ .getSingleResult();
+
+ assertEquals(dbPerson.getPersonName(), null);
+ }
+
}
diff --git a/jackson/pom.xml b/jackson/pom.xml
index 001fde5021..2587e61ac1 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -129,7 +129,7 @@
- 2.9.2
+ 2.9.419.0
diff --git a/java-lite/pom.xml b/java-lite/pom.xml
index eb18bc40a5..d7950487ca 100644
--- a/java-lite/pom.xml
+++ b/java-lite/pom.xml
@@ -1,7 +1,6 @@
-
+4.0.0org.baeldung
@@ -22,10 +21,15 @@
5.1.451.7.01.8.2
- 4.11
+ 4.12
+
+
+ src/main/webapp/WEB-INF
+
+ org.eclipse.jetty
@@ -85,7 +89,14 @@
system${java.home}/../lib/tools.jar
-
+
+
+ org.javalite
+ activeweb-testing
+ 1.15
+ test
+
+
junitjunit
diff --git a/java-lite/src/main/java/app/config/AppBootstrap.java b/java-lite/src/main/java/app/config/AppBootstrap.java
index 7a87c2d0a7..02c8360986 100644
--- a/java-lite/src/main/java/app/config/AppBootstrap.java
+++ b/java-lite/src/main/java/app/config/AppBootstrap.java
@@ -3,7 +3,15 @@ package app.config;
import org.javalite.activeweb.AppContext;
import org.javalite.activeweb.Bootstrap;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import app.services.ArticleServiceModule;
+
public class AppBootstrap extends Bootstrap {
public void init(AppContext context) {
}
+ public Injector getInjector() {
+ return Guice.createInjector(new ArticleServiceModule());
+ }
}
diff --git a/java-lite/src/main/java/app/controllers/ArticleController.java b/java-lite/src/main/java/app/controllers/ArticleController.java
new file mode 100755
index 0000000000..2b8dc452bd
--- /dev/null
+++ b/java-lite/src/main/java/app/controllers/ArticleController.java
@@ -0,0 +1,28 @@
+package app.controllers;
+
+import javax.inject.Inject;
+
+import org.javalite.activeweb.AppController;
+
+import app.services.ArticleService;
+
+public class ArticleController extends AppController {
+
+ @Inject
+ private ArticleService articleService;
+
+ public void index() {
+ view("articles", articleService.getArticles());
+ }
+
+ public void search() {
+
+ String keyword = param("key");
+ if (null != keyword) {
+ assign("article", articleService.search(keyword));
+ } else {
+ render("/common/error");
+ }
+
+ }
+}
diff --git a/java-lite/src/main/java/app/controllers/HomeController.java b/java-lite/src/main/java/app/controllers/HomeController.java
new file mode 100755
index 0000000000..0e284af0ad
--- /dev/null
+++ b/java-lite/src/main/java/app/controllers/HomeController.java
@@ -0,0 +1,11 @@
+package app.controllers;
+
+import org.javalite.activeweb.AppController;
+
+public class HomeController extends AppController {
+
+ public void index() {
+ render("index");
+ }
+
+}
diff --git a/java-lite/src/main/java/app/models/Article.java b/java-lite/src/main/java/app/models/Article.java
new file mode 100755
index 0000000000..db318f4468
--- /dev/null
+++ b/java-lite/src/main/java/app/models/Article.java
@@ -0,0 +1,50 @@
+package app.models;
+
+public class Article {
+
+ private String title;
+ private String author;
+ private String words;
+ private String date;
+
+ public Article(String title, String author, String words, String date) {
+ super();
+ this.title = title;
+ this.author = author;
+ this.words = words;
+ this.date = date;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public String getWords() {
+ return words;
+ }
+
+ public void setWords(String words) {
+ this.words = words;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+}
\ No newline at end of file
diff --git a/java-lite/src/main/java/app/services/ArticleService.java b/java-lite/src/main/java/app/services/ArticleService.java
new file mode 100755
index 0000000000..ddd0b3ed10
--- /dev/null
+++ b/java-lite/src/main/java/app/services/ArticleService.java
@@ -0,0 +1,13 @@
+package app.services;
+
+import java.util.List;
+
+import app.models.Article;
+
+public interface ArticleService {
+
+ List getArticles();
+
+ Article search(String keyword);
+
+}
diff --git a/java-lite/src/main/java/app/services/ArticleServiceImpl.java b/java-lite/src/main/java/app/services/ArticleServiceImpl.java
new file mode 100755
index 0000000000..fc81576f91
--- /dev/null
+++ b/java-lite/src/main/java/app/services/ArticleServiceImpl.java
@@ -0,0 +1,34 @@
+package app.services;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+
+import app.models.Article;
+
+public class ArticleServiceImpl implements ArticleService {
+
+ public List getArticles() {
+ return fetchArticles();
+ }
+
+ public Article search(String keyword) {
+ Article ar = new Article("Article with " + keyword, "baeldung", "1250", Instant.now()
+ .toString());
+ return ar;
+ }
+
+ private List fetchArticles() {
+ Article ar1 = new Article("Introduction to ActiveWeb", "baeldung", "1650", Instant.now()
+ .toString());
+
+ Article ar = new Article("Introduction to Mule", "baeldung", "1650", Instant.now()
+ .toString());
+ List articles = new ArrayList();
+ articles.add(ar);
+ articles.add(ar1);
+ return articles;
+
+ }
+
+}
diff --git a/java-lite/src/main/java/app/services/ArticleServiceModule.java b/java-lite/src/main/java/app/services/ArticleServiceModule.java
new file mode 100755
index 0000000000..feae2a2ff7
--- /dev/null
+++ b/java-lite/src/main/java/app/services/ArticleServiceModule.java
@@ -0,0 +1,12 @@
+package app.services;
+
+import com.google.inject.AbstractModule;
+
+public class ArticleServiceModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(ArticleService.class).to(ArticleServiceImpl.class)
+ .asEagerSingleton();
+ }
+}
diff --git a/java-lite/src/main/webapp/WEB-INF/views/article/index.ftl b/java-lite/src/main/webapp/WEB-INF/views/article/index.ftl
new file mode 100755
index 0000000000..2d5f211427
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/article/index.ftl
@@ -0,0 +1,18 @@
+<@content for="title">Articles@content>
+
+
+
+
Title
+
Author
+
Words #
+
Date Published
+
+<#list articles as article>
+
+
${article.title}
+
${article.author}
+
${article.words}
+
${article.date}
+
+#list>
+
\ No newline at end of file
diff --git a/java-lite/src/main/webapp/WEB-INF/views/article/search.ftl b/java-lite/src/main/webapp/WEB-INF/views/article/search.ftl
new file mode 100755
index 0000000000..45a73808ed
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/article/search.ftl
@@ -0,0 +1,17 @@
+<@content for="title">Search@content>
+
+
+
+
Title
+
Author
+
Words #
+
Date Published
+
+
+
${article.title}
+
${article.author}
+
${article.words}
+
${article.date}
+
+
+
\ No newline at end of file
diff --git a/java-lite/src/main/webapp/WEB-INF/views/common/error.ftl b/java-lite/src/main/webapp/WEB-INF/views/common/error.ftl
new file mode 100755
index 0000000000..5fbf3c5243
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/common/error.ftl
@@ -0,0 +1,3 @@
+<@content for="title">Simple Web App@content>
+
+
Application error
diff --git a/java-lite/src/main/webapp/WEB-INF/views/home/index.ftl b/java-lite/src/main/webapp/WEB-INF/views/home/index.ftl
new file mode 100755
index 0000000000..ae6a7c56a5
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/home/index.ftl
@@ -0,0 +1,3 @@
+<@content for="title">Simple Web App@content>
+
+