ConcurrentEvaluator implements Evaluator<G, C> { @Override public ISeq<Phenotype<G, C>> eval(final Seq<Phenotype<G, C>> population) { final ISeq<PhenotypeFitness<G, C>> evaluate = population.stream() .filter(Phenotype::nonEvaluated) .map(pt -> new PhenotypeFitness<>(pt, _function)) .collect(ISeq.toISeq()); final ISeq<Phenotype<G, C>> result; if (evaluate.nonEmpty()) { try (var c = Concurrency.with(_executor)) { c.execute(evaluate); } result = evaluate.size() == population.size() ? evaluate.map(PhenotypeFitness::phenotype) : population.stream() .filter(Phenotype::isEvaluated) .collect(ISeq.toISeq()) .append(evaluate.map(PhenotypeFitness::phenotype)); } else { result = population.asISeq(); } return result; } ConcurrentEvaluator(
		final Function<? super Genotype<G>, ? extends C> function,
		final Executor executor
	); @Override ISeq<Phenotype<G, C>> eval(final Seq<Phenotype<G, C>> population);  }
@Test public void evaluateSerial() { final ISeq<Phenotype<DoubleGene, Double>> phenotypes = Genotype.of(DoubleChromosome.of(0, 1)).instances() .limit(100) .map(gt -> Phenotype.<DoubleGene, Double>of(gt, 1)) .collect(ISeq.toISeq()); phenotypes.forEach(pt -> Assert.assertTrue(pt.nonEvaluated())); final Evaluator<DoubleGene, Double> evaluator = new ConcurrentEvaluator<>(gt -> gt.gene().doubleValue(), Runnable::run); final ISeq<Phenotype<DoubleGene, Double>> evaluated = evaluator.eval(phenotypes); evaluated.forEach(pt -> Assert.assertEquals(pt.genotype().gene().allele(), pt.fitness())); }