PopulationIterator.java

1
package net.bmahe.genetics4j.core;
2
3
import java.util.Iterator;
4
import java.util.Objects;
5
6
/**
7
 * Iterator implementation for traversing individuals in a population during evolutionary algorithms.
8
 * 
9
 * <p>PopulationIterator provides a standard Java Iterator interface for accessing individuals in a {@link Population},
10
 * combining genotypes with their corresponding fitness values to create complete {@link Individual} instances during
11
 * iteration.
12
 * 
13
 * <p>This iterator enables convenient traversal patterns such as:
14
 * <ul>
15
 * <li><strong>Enhanced for loops</strong>: Iterate over individuals using for-each syntax</li>
16
 * <li><strong>Stream operations</strong>: Convert populations to streams for functional processing</li>
17
 * <li><strong>Sequential access</strong>: Process individuals one at a time without loading all into memory</li>
18
 * <li><strong>Collection integration</strong>: Use with Java Collection framework methods</li>
19
 * </ul>
20
 * 
21
 * <p>The iterator maintains internal state to track the current position and constructs {@link Individual} objects
22
 * on-demand by combining genotypes and fitness values from the underlying population at the same index.
23
 * 
24
 * <p>Key characteristics:
25
 * <ul>
26
 * <li><strong>Type safety</strong>: Parameterized with fitness type for compile-time type checking</li>
27
 * <li><strong>Lazy evaluation</strong>: Creates Individual objects only when requested</li>
28
 * <li><strong>Memory efficient</strong>: Doesn't duplicate population data, references original</li>
29
 * <li><strong>Standard interface</strong>: Implements Java Iterator contract completely</li>
30
 * </ul>
31
 * 
32
 * <p>Usage patterns:
33
 * 
34
 * <pre>{@code
35
 * // Enhanced for loop iteration
36
 * Population<Double> population = getPopulation();
37
 * for (Individual<Double> individual : population) {
38
 * 	System.out.println("Fitness: " + individual.fitness());
39
 * }
40
 * 
41
 * // Stream-based processing
42
 * population.stream()
43
 * 		.filter(individual -> individual.fitness() > threshold)
44
 * 		.mapToDouble(Individual::fitness)
45
 * 		.average();
46
 * 
47
 * // Manual iteration
48
 * Iterator<Individual<Double>> iterator = population.iterator();
49
 * while (iterator.hasNext()) {
50
 * 	Individual<Double> individual = iterator.next();
51
 * 	processIndividual(individual);
52
 * }
53
 * }</pre>
54
 * 
55
 * <p>Thread safety considerations:
56
 * <ul>
57
 * <li><strong>Single-threaded use</strong>: Iterator instances are not thread-safe</li>
58
 * <li><strong>Population stability</strong>: Underlying population should not be modified during iteration</li>
59
 * <li><strong>Concurrent iterations</strong>: Multiple iterators can be created for the same population</li>
60
 * </ul>
61
 * 
62
 * @param <T> the type of fitness values in the population, must be comparable for selection operations
63
 * @see Population
64
 * @see Individual
65
 * @see java.util.Iterator
66
 */
67
public class PopulationIterator<T extends Comparable<T>> implements Iterator<Individual<T>> {
68
69
	private final Population<T> population;
70
71 2 1. <init> : Removed assignment to member variable currentIndex → SURVIVED
2. <init> : Substituted 0 with 1 → KILLED
	private int currentIndex = 0;
72
73
	/**
74
	 * Constructs a new iterator for the specified population.
75
	 * 
76
	 * <p>Creates an iterator that will traverse all individuals in the given population, starting from index 0 and
77
	 * proceeding sequentially through all individuals.
78
	 * 
79
	 * @param _population the population to iterate over
80
	 * @throws IllegalArgumentException if the population is null
81
	 */
82
	public PopulationIterator(final Population<T> _population) {
83
		Objects.requireNonNull(_population);
84
85 1 1. <init> : Removed assignment to member variable population → KILLED
		this.population = _population;
86
	}
87
88
	/**
89
	 * Returns {@code true} if there are more individuals to iterate over.
90
	 * 
91
	 * <p>Checks whether the current position is within the bounds of the population. This method can be called multiple
92
	 * times without advancing the iterator position.
93
	 * 
94
	 * @return {@code true} if there are more individuals, {@code false} if all have been visited
95
	 */
96
	@Override
97
	public boolean hasNext() {
98 8 1. hasNext : Substituted 1 with 0 → KILLED
2. hasNext : changed conditional boundary → KILLED
3. hasNext : removed call to net/bmahe/genetics4j/core/Population::size → KILLED
4. hasNext : removed conditional - replaced comparison check with true → KILLED
5. hasNext : removed conditional - replaced comparison check with false → KILLED
6. hasNext : Substituted 0 with 1 → KILLED
7. hasNext : replaced boolean return with true for net/bmahe/genetics4j/core/PopulationIterator::hasNext → KILLED
8. hasNext : negated conditional → KILLED
		return currentIndex < population.size();
99
	}
100
101
	/**
102
	 * Returns the next individual in the population and advances the iterator position.
103
	 * 
104
	 * <p>Constructs an {@link Individual} by combining the genotype and fitness value at the current position, then
105
	 * advances to the next position for subsequent calls.
106
	 * 
107
	 * @return the next individual in the iteration sequence
108
	 * @throws java.util.NoSuchElementException if there are no more individuals (when {@link #hasNext()} returns false)
109
	 */
110
	@Override
111
	public Individual<T> next() {
112 1 1. next : removed call to net/bmahe/genetics4j/core/Population::getGenotype → KILLED
		final Genotype genotype = population.getGenotype(currentIndex);
113 1 1. next : removed call to net/bmahe/genetics4j/core/Population::getFitness → KILLED
		final T fitness = population.getFitness(currentIndex);
114 3 1. next : Removed assignment to member variable currentIndex → KILLED
2. next : Replaced integer addition with subtraction → KILLED
3. next : Substituted 1 with 0 → KILLED
		currentIndex++;
115 2 1. next : replaced return value with null for net/bmahe/genetics4j/core/PopulationIterator::next → KILLED
2. next : removed call to net/bmahe/genetics4j/core/Individual::of → KILLED
		return Individual.of(genotype, fitness);
116
	}
117
}

Mutations

71

1.1
Location : <init>
Killed by : none
Removed assignment to member variable currentIndex → SURVIVED
Covering tests

2.2
Location : <init>
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()]
Substituted 0 with 1 → KILLED

85

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()]
Removed assignment to member variable population → KILLED

98

1.1
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnNonEmptyPopulation()]
Substituted 1 with 0 → KILLED

2.2
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()]
changed conditional boundary → KILLED

3.3
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnNonEmptyPopulation()]
removed call to net/bmahe/genetics4j/core/Population::size → KILLED

4.4
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()]
removed conditional - replaced comparison check with true → KILLED

5.5
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnNonEmptyPopulation()]
removed conditional - replaced comparison check with false → KILLED

6.6
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()]
Substituted 0 with 1 → KILLED

7.7
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()]
replaced boolean return with true for net/bmahe/genetics4j/core/PopulationIterator::hasNext → KILLED

8.8
Location : hasNext
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:hasNextOnEmptyPopulation()]
negated conditional → KILLED

112

1.1
Location : next
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()]
removed call to net/bmahe/genetics4j/core/Population::getGenotype → KILLED

113

1.1
Location : next
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()]
removed call to net/bmahe/genetics4j/core/Population::getFitness → KILLED

114

1.1
Location : next
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAdvancesIterator()]
Removed assignment to member variable currentIndex → KILLED

2.2
Location : next
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAdvancesIterator()]
Replaced integer addition with subtraction → KILLED

3.3
Location : next
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextAdvancesIterator()]
Substituted 1 with 0 → KILLED

115

1.1
Location : next
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()]
replaced return value with null for net/bmahe/genetics4j/core/PopulationIterator::next → KILLED

2.2
Location : next
Killed by : net.bmahe.genetics4j.core.PopulationIteratorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.PopulationIteratorTest]/[method:nextReturnsCorrectIndividual()]
removed call to net/bmahe/genetics4j/core/Individual::of → KILLED

Active mutators

Tests examined


Report generated by PIT 1.25.7 support