0

how to use various collections to create objects by combining data from these diverse collections

I have 8 different collections and need IDs to iterate through all of them to generate objects that combine these ids.

Suppose I have as input the following collections ids: colors, heights, lengths, widths, materials, thicknesses, textures and effects.

And I want to create a new collection of objects that combine all these features.

So if each of these input collections have 2 items, at the end I would have a new collection containing 2 x 2 x 2 x 2 x 2 x 2 x 2 x 2 = 256 objects containing all possible combinations of these characteristics.

How to do this efficiently using Java?

  • Hi PH, what you want is called a combination of elements, there are some solutions for it in another answers but one I believe can help you out is this one: http://stackoverflow.com/a/17193002/673086 – Fabricio Buzeto Oct 13 '16 at 14:48
  • Possible duplicate of [Generate all combinations from multiple lists](http://stackoverflow.com/questions/17192796/generate-all-combinations-from-multiple-lists) – Fabricio Buzeto Oct 13 '16 at 14:48
  • Thanks @FabricioBuzeto. How to combine that solution and call the correct set method of each feature? The first iteration I can set the color, the second iteration set the heights... – Paulo Rodrigues Oct 13 '16 at 15:11
  • You can achieve this whenever you reach a leaf of your combination tree (`depth == Lists.size() - 1`) and then, just consider the arguments in the same order of your `Lists`. – Fabricio Buzeto Oct 13 '16 at 18:00

1 Answers1

0

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
...
siordache
  • 112
  • 1
  • 3