Merge remote-tracking branch 'eugenp/master'
This commit is contained in:
@@ -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() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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:
|
||||
*
|
||||
* <pre>
|
||||
* ({@link Constants#INERTIA_FACTOR} * {@link Particle#getSpeed()}) +
|
||||
* (({@link Constants#COGNITIVE_WEIGHT} * random(0,1)) * ({@link Particle#getBestPosition()} - {@link Particle#getPosition()})) +
|
||||
* (({@link Constants#SOCIAL_WEIGHT} * random(0,1)) * ({@link Swarm#getBestPosition()} - {@link Particle#getPosition()})) +
|
||||
* (({@link Constants#GLOBAL_WEIGHT} * random(0,1)) * ({@link #bestPosition} - {@link Particle#getPosition()}))
|
||||
* </pre>
|
||||
*
|
||||
* @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 + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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: <br>
|
||||
* <br>
|
||||
* 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? <br>
|
||||
* <br>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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: <br>
|
||||
* <br>
|
||||
* 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? <br>
|
||||
* <br>
|
||||
* 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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>checker-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>checker-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<!-- https://checkerframework.org/manual/#maven -->
|
||||
|
||||
<properties>
|
||||
<!-- These properties will be set by the Maven Dependency plugin -->
|
||||
<annotatedJdk>${org.checkerframework:jdk8:jar}</annotatedJdk>
|
||||
<!-- Uncomment to use the Type Annotations compiler. -->
|
||||
<!--
|
||||
<typeAnnotationsJavac>${org.checkerframework:compiler:jar}</typeAnnotationsJavac>
|
||||
-->
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- Annotations from the Checker Framework: nullness, interning, locking, ... -->
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>jdk8</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<!-- The Type Annotations compiler. Uncomment if using annotations in comments. -->
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>compiler</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<!-- This plugin will set properties values using dependency information -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<!--
|
||||
Goal that sets a property pointing to the artifact file for each project dependency.
|
||||
For each dependency (direct and transitive) a project property will be set which
|
||||
follows the:
|
||||
|
||||
groupId:artifactId:type:[classifier]
|
||||
|
||||
form and contains the path to the resolved artifact. -->
|
||||
<goal>properties</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<!-- Uncomment the following line to use the type annotations compiler. -->
|
||||
<!-- <fork>true</fork> -->
|
||||
<compilerArguments>
|
||||
<Xmaxerrs>10000</Xmaxerrs>
|
||||
<Xmaxwarns>10000</Xmaxwarns>
|
||||
</compilerArguments>
|
||||
<annotationProcessors>
|
||||
<!-- Add all the checkers you want to enable here -->
|
||||
<annotationProcessor>org.checkerframework.checker.nullness.NullnessChecker</annotationProcessor>
|
||||
<annotationProcessor>org.checkerframework.checker.interning.InterningChecker</annotationProcessor>
|
||||
<annotationProcessor>org.checkerframework.checker.fenum.FenumChecker</annotationProcessor>
|
||||
<annotationProcessor>org.checkerframework.checker.formatter.FormatterChecker</annotationProcessor>
|
||||
<annotationProcessor>org.checkerframework.checker.regex.RegexChecker</annotationProcessor>
|
||||
</annotationProcessors>
|
||||
<compilerArgs>
|
||||
<arg>-AprintErrorStack</arg>
|
||||
|
||||
<!-- location of the annotated JDK, which comes from a Maven dependency -->
|
||||
<arg>-Xbootclasspath/p:${annotatedJdk}</arg>
|
||||
<!--
|
||||
-->
|
||||
|
||||
<!-- Uncomment the following line to use the type annotations compiler. -->
|
||||
<!--
|
||||
<arg>-J-Xbootclasspath/p:${typeAnnotationsJavac}</arg>
|
||||
-->
|
||||
<!-- Uncomment the following line to turn type-checking warnings into errors. -->
|
||||
<arg>-Awarns</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# Groovy
|
||||
|
||||
## Relevant articles:
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>core-groovy</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<version>2.4.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-sql</artifactId>
|
||||
<version>2.4.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>addSources</goal>
|
||||
<goal>addTestSources</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>compileTests</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>2.19.1</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>junit5</id>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test5.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<kotlin-maven-plugin.version>1.1.2</kotlin-maven-plugin.version>
|
||||
<kotlin-test-junit.version>1.1.2</kotlin-test-junit.version>
|
||||
<kotlin-stdlib.version>1.1.2</kotlin-stdlib.version>
|
||||
<kotlin-reflect.version>1.1.2</kotlin-reflect.version>
|
||||
<kotlinx.version>0.15</kotlinx.version>
|
||||
<mockito-kotlin.version>1.5.0</mockito-kotlin.version>
|
||||
|
||||
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<junit.vintage.version>4.12.0</junit.vintage.version>
|
||||
<junit4.version>4.12</junit4.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -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 '))
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ public class ShufflingCollectionsUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenShufflingMapKeys_thenValuesAreShuffled() {
|
||||
public void whenShufflingMapEntries_thenValuesAreShuffled() {
|
||||
Map<Integer, String> studentsById = new HashMap<>();
|
||||
studentsById.put(1, "Foo");
|
||||
studentsById.put(2, "Bar");
|
||||
@@ -32,12 +32,12 @@ public class ShufflingCollectionsUnitTest {
|
||||
System.out.println("Students before shuffling:");
|
||||
System.out.println(studentsById.values());
|
||||
|
||||
List<Integer> shuffledStudentIds = new ArrayList<>(studentsById.keySet());
|
||||
Collections.shuffle(shuffledStudentIds);
|
||||
List<Map.Entry<Integer, String>> shuffledStudentEntries = new ArrayList<>(studentsById.entrySet());
|
||||
Collections.shuffle(shuffledStudentEntries);
|
||||
|
||||
List<String> shuffledStudents = shuffledStudentIds.stream()
|
||||
.map(id -> studentsById.get(id))
|
||||
.collect(Collectors.toList());
|
||||
List<String> shuffledStudents = shuffledStudentEntries.stream()
|
||||
.map(Map.Entry::getValue)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
System.out.println("Students after shuffling");
|
||||
System.out.println(shuffledStudents);
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
@@ -127,3 +127,4 @@
|
||||
- [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)
|
||||
|
||||
@@ -78,6 +78,11 @@
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- logging -->
|
||||
<dependency>
|
||||
@@ -468,6 +473,7 @@
|
||||
<properties>
|
||||
<!-- marshalling -->
|
||||
<jackson.version>2.8.5</jackson.version>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
|
||||
<!-- logging -->
|
||||
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.casting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AnimalFeeder {
|
||||
|
||||
public void feed(List<Animal> animals) {
|
||||
animals.forEach(animal -> {
|
||||
animal.eat();
|
||||
if (animal instanceof Cat) {
|
||||
((Cat) animal).meow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void uncheckedFeed(List<Animal> animals) {
|
||||
animals.forEach(animal -> {
|
||||
animal.eat();
|
||||
((Cat) animal).meow();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.casting;
|
||||
|
||||
public interface Mew {
|
||||
public void meow();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user