The code below uses the Streamplify library and assumes that you have a class called Characteristics with accessor methods for your features. See full implementation here.
private static class Feature<T> {
final BiConsumer<Characteristics, T> setter;
final List<T> choices;
Feature(BiConsumer<Characteristics, T> setter, T... choices) {
this.setter = setter;
this.choices = Arrays.asList(choices);
}
}
public static void main(String[] args) {
final List<Feature<?>> features = Arrays.asList(
new Feature<Color>(Characteristics::setColor, Color.BLUE, Color.YELLOW, Color.RED),
new Feature<Integer>(Characteristics::setHeight, 20, 30),
new Feature<Integer>(Characteristics::setLength, 100, 120),
new Feature<Integer>(Characteristics::setWidth, 60, 80),
new Feature<String>(Characteristics::setMaterial, "wood", "metal", "glass"),
new Feature<Integer>(Characteristics::setThickness, 4, 6),
new Feature<String>(Characteristics::setTexture, "smooth", "grainy", "velvety"),
new Feature<Effect>(Characteristics::setEffect, new Shadow(), new BoxBlur())
);
int[] dimensions = features.stream().mapToInt(f -> f.choices.size()).toArray();
List<Characteristics> chrVariants = new CartesianProduct(dimensions)
.stream()
.map(prod -> {
Characteristics chr = new Characteristics();
IntStream.range(0, prod.length)
.forEach(i -> {
Feature f = features.get(i);
f.setter.accept(chr, f.choices.get(prod[i]));
});
return chr;
})
.collect(Collectors.toList());
chrVariants.forEach(chr -> System.out.println(chr));
}
Output:
0x0000ffff, 20, 100, 60, wood, 4, smooth, Shadow
0x0000ffff, 20, 100, 60, wood, 4, smooth, BoxBlur
0x0000ffff, 20, 100, 60, wood, 4, grainy, Shadow
0x0000ffff, 20, 100, 60, wood, 4, grainy, BoxBlur
0x0000ffff, 20, 100, 60, wood, 4, velvety, Shadow
0x0000ffff, 20, 100, 60, wood, 4, velvety, BoxBlur
0x0000ffff, 20, 100, 60, wood, 6, smooth, Shadow
0x0000ffff, 20, 100, 60, wood, 6, smooth, BoxBlur
0x0000ffff, 20, 100, 60, wood, 6, grainy, Shadow
0x0000ffff, 20, 100, 60, wood, 6, grainy, BoxBlur
0x0000ffff, 20, 100, 60, wood, 6, velvety, Shadow
0x0000ffff, 20, 100, 60, wood, 6, velvety, BoxBlur
0x0000ffff, 20, 100, 60, metal, 4, smooth, Shadow
0x0000ffff, 20, 100, 60, metal, 4, smooth, BoxBlur
...