I'm trying to get more familiar with the new Java 8 features, so I am rewriting one of my earlier projects. It includes a class that keeps track of the best entry seen so far:
import java.util.List;
public class Maxinator<T> {
private final QualityFunction<T> qualityFunction;
private T best;
private double bestQuality;
public Maxinator(QualityFunction<T> qualityFunction) {
this.qualityFunction = qualityFunction;
reset();
}
public void reset() {
best = null;
bestQuality = Double.NEGATIVE_INFINITY;
}
public T getBest() {
return best;
}
public void updateBest(List<T> population) {
population.parallelStream()
.forEach(i -> {
double quality = qualityFunction.computeQuality(i);
if (quality > bestQuality) {
best = i;
bestQuality = quality;
}
});
}
}
Where QualityFunction
is simply the following interface:
public interface QualityFunction<T> {
public abstract double computeQuality(T individual);
}
My questions:
- Are there any concurrency issues with the code in the
forEach
modifyingbest
andbestQuality
? Or are these automatically taken care of by the parallel stream processing? - Is there a more idiomatic way to write this, using the new APIs (
collect
,reduce
, etc.)?
Note: the quality function could be very expensive, so I want to make sure that it is only called once per element.