Codecs { public static <A, B, M extends Map<A, B>> InvertibleCodec<M, EnumGene<Integer>> ofMapping( final ISeq<? extends A> source, final ISeq<? extends B> target, final Supplier<M> mapSupplier ) { requireNonNull(source); requireNonNull(target); requireNonNull(mapSupplier); final Map<A, Integer> smap = IntStream.range(0, source.length()) .mapToObj(i -> entry(source.get(i), i)) .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); final Map<B, Integer> tmap = IntStream.range(0, target.length()) .mapToObj(i -> entry(target.get(i), i)) .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); final PermutationChromosome<Integer> chromosome = PermutationChromosome.ofInteger(target.size()); final Map<Integer, EnumGene<Integer>> genes = chromosome.stream() .collect(Collectors.toMap(EnumGene::allele, identity())); final Codec<int[], EnumGene<Integer>> codec = Codec.of( Genotype.of(chromosome), gt -> gt.chromosome().stream() .mapToInt(EnumGene::allele) .toArray() ); return codec .map(permutation -> toMapping(permutation, source, target, mapSupplier)) .toInvertibleCodec(mapping -> toEncoding(mapping, smap,tmap, genes)); } private  Codecs(); static InvertibleCodec<Integer, IntegerGene> ofScalar(final IntRange domain); static InvertibleCodec<Long, LongGene> ofScalar(final LongRange domain); static InvertibleCodec<Double, DoubleGene> ofScalar(final DoubleRange domain); static Codec<A, AnyGene<A>> ofScalar(
		final Supplier<? extends A> supplier,
		final Predicate<? super A> validator
	); static Codec<A, AnyGene<A>> ofScalar(
		final Supplier<? extends A> supplier
	); static InvertibleCodec<int[], IntegerGene> ofVector(
		final IntRange domain,
		final int length
	); static InvertibleCodec<long[], LongGene> ofVector(
		final LongRange domain,
		final int length
	); static InvertibleCodec<double[], DoubleGene> ofVector(
		final DoubleRange domain,
		final int length
	); static InvertibleCodec<int[], IntegerGene> ofVector(final IntRange... domains); static InvertibleCodec<long[], LongGene> ofVector(final LongRange... domains); static InvertibleCodec<double[], DoubleGene> ofVector(final DoubleRange... domains); static Codec<ISeq<A>, AnyGene<A>> ofVector(
		final Supplier<? extends A> supplier,
		final Predicate<? super A> alleleValidator,
		final Predicate<? super ISeq<A>> alleleSeqValidator,
		final int length
	); static Codec<ISeq<A>, AnyGene<A>> ofVector(
		final Supplier<? extends A> supplier,
		final Predicate<? super A> validator,
		final int length
	); static Codec<ISeq<A>, AnyGene<A>> ofVector(
		final Supplier<? extends A> supplier,
		final int length
	); static InvertibleCodec<int[], EnumGene<Integer>> ofPermutation(final int length); static InvertibleCodec<ISeq<T>, EnumGene<T>> ofPermutation(final ISeq<? extends T> alleles); static InvertibleCodec<int[][], IntegerGene> ofMatrix(
		final IntRange domain,
		final int rows,
		final int cols
	); static InvertibleCodec<long[][], LongGene> ofMatrix(
		final LongRange domain,
		final int rows,
		final int cols
	); static InvertibleCodec<double[][], DoubleGene> ofMatrix(
		final DoubleRange domain,
		final int rows,
		final int cols
	); static InvertibleCodec<M, EnumGene<Integer>> ofMapping(
		final ISeq<? extends A> source,
		final ISeq<? extends B> target,
		final Supplier<M> mapSupplier
	); static InvertibleCodec<Map<A, B>, EnumGene<Integer>> ofMapping(final ISeq<? extends A> source, final ISeq<? extends B> target); static InvertibleCodec<ISeq<T>, BitGene> ofSubSet(final ISeq<? extends T> basicSet); static InvertibleCodec<ISeq<T>, EnumGene<T>> ofSubSet(
		final ISeq<? extends T> basicSet,
		final int size
	);  }
@Test public void ofMapping1() { final ISeq<Integer> numbers = ISeq.of(1, 2, 3, 4, 5); final ISeq<String> chars = ISeq.of("A", "B", "C"); final Codec<Map<Integer, String>, EnumGene<Integer>> codec = Codecs.ofMapping(numbers, chars); final Function<Map<Integer, String>, Integer> ff = map -> map.keySet().stream().mapToInt(Integer::intValue).sum(); Engine<EnumGene<Integer>, Integer> engine = Engine.builder(ff, codec) .build(); final Map<Integer, String> best = codec.decode( engine.stream() .limit(100) .collect(EvolutionResult.toBestGenotype()) ); assertTrue(best.containsKey(3)); assertTrue(best.containsKey(4)); assertTrue(best.containsKey(5)); }
@Test public void ofMapping2() { final ISeq<Integer> numbers = ISeq.of(1, 2, 3, 4, 5); final ISeq<String> chars = ISeq.of("A", "B", "C"); final Codec<Map<String, Integer>, EnumGene<Integer>> codec = Codecs.ofMapping(chars, numbers); final Function<Map<String, Integer>, Integer> ff = map -> map.values().stream().mapToInt(Integer::intValue).sum(); Engine<EnumGene<Integer>, Integer> engine = Engine.builder(ff, codec) .build(); final Map<String, Integer> best = codec.decode( engine.stream() .limit(100) .collect(EvolutionResult.toBestGenotype()) ); assertTrue(best.containsValue(3)); assertTrue(best.containsValue(4)); assertTrue(best.containsValue(5)); }