Find all possible combination of listings

Is there an efficient way to find all possible combinations between multiple enums in Java?

Consider the following three listings:

public enum EnumOne { One ("One"), OneMore ("OneMore"); } public enum EnumTwo { Two ("Two"), } public enum EnumThree { Three ("Three"), ThreeMore ("ThreeMore"); } 

I would like the result to produce all possible combinations between these multiple enumerations i.e.

 {EnumOne.One, EnumTwo.Two, EnumThree.Three}, {EnumOne.One, EnumTwo.Two, EnumThree.ThreeMore}, {EnumOne.OneMore, EnumTwo.Two, EnumThree.Three}, {EnumOne.OneMore, EnumTwo.Two, EnumThree.ThreeMore} 

Hoping to find an effective way to handle it.

thanks

+6
source share
3 answers

the complexity of the O (NxMxK ​​.... xZ) algorithms , if I am mistaken , I do not know if this is an "efficient way" .... I use as the opposite solution

 import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ProductEnums { public enum EnumOne { One, OneMore; } public enum EnumTwo { Two, } public enum EnumThree { Three, ThreeMore; } public static void main(String[] args) { // pass each values in enums List a = product(EnumOne.values(), EnumTwo.values(), EnumThree.values()); System.out.println(a); } public static List<List<Enum>> product(Enum[]... enums) { return product(new ArrayList<>(Arrays.asList(enums))); } public static List<List<Enum>> product(List<Enum[]> enums) { if (enums.isEmpty()) { //Trivial case of recursive function return new ArrayList<>(); } //remove first element Enum[] myEnums = enums.remove(0); List<List<Enum>> out = new ArrayList<>(); for (Enum e : myEnums) { //call recursive List<List<Enum>> list = product(enums); for (List<Enum> list_enum : list) { //for each list get from recursion adding element e list_enum.add(0, e); out.add(list_enum); } if(list.isEmpty()){ List<Enum> list_enum = new ArrayList<>(); list_enum.add(e); out.add(list_enum); } } enums.add(0, myEnums); //Backtraking return out; } } 

Result

[[One, Two, Three], [One, Two, ThreeMore], [OneMore, Two, Three], [OneMore, Two, ThreeMore]]

0
source

Here is an iterator based solution. Thus, memory consumption will not explode if it works in many types of enumerations with loads of constants of the enumerated type. Execution efficiency should be excellent (in addition, implementation avoids recursion).

 import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; public class EnumCombination implements Iterable<Enum<?>[]> { private final Enum<?>[][] enumConstants; private final int[] limits; private final boolean emptyCombination; public EnumCombination(final List<Class<? extends Enum<?>>> enums) { this.limits = new int[enums.size()]; this.enumConstants = new Enum<?>[enums.size()][]; boolean empty = enums.isEmpty(); for (int i = 0; i < enums.size(); i++) { final Enum<?>[] enumElements = enums.get(i).getEnumConstants(); enumConstants[i] = enumElements; limits[i] = enumElements.length - 1; empty |= enumElements.length == 0; } this.emptyCombination = empty; } @Override public Iterator<Enum<?>[]> iterator() { return new EnumCombinationIterator(); } private class EnumCombinationIterator implements Iterator<Enum<?>[]> { private final int[] cursors = new int[limits.length]; private boolean exhausted = emptyCombination; @Override public boolean hasNext() { return !exhausted; } @Override public Enum<?>[] next() { if (exhausted) throw new NoSuchElementException(); final Enum<?>[] result = new Enum<?>[cursors.length]; for (int i = 0; i < cursors.length; i++) { result[i] = enumConstants[i][cursors[i]]; } moveCursors(); return result; } private void moveCursors() { for (int i = cursors.length - 1; i >= 0; i--) { cursors[i] = cursors[i] == limits[i] ? 0 : cursors[i] + 1; if (cursors[i] != 0) { break; } else if (i == 0) { exhausted = true; } } } } } 

EnumCombination can be used as follows:

 import java.util.*; public class Main { public enum EnumOne { One, OneMore } public enum EnumTwo { Two } public enum EnumThree { Three, ThreeMore } public static void main(String... args) { EnumCombination enumCombination = new EnumCombination( Arrays.asList(EnumOne.class, EnumTwo.class, EnumThree.class)); for (final Enum<?>[] ec : enumCombination) { System.out.println(Arrays.toString(ec)); } } } 

But, of course, one could use guavas cartesianProduct() as well ...

0
source

How about something like that.

 void printAll(List<Class> enums, int i, String[] msg) { if (!enums.get(i).isEnum()) { throw new IllegalStateException(); } Object[] enumsConstants = enums.get(i).getEnumConstants(); if (i == 0) { //first iteration for (Object o : enumsConstants) { if (enums.size() == 1) { System.out.println("{ " + o.toString() + " }"); } else { msg = new String[enums.size()]; msg[0] = "{ " + o.toString(); printAll(enums, i + 1, msg); } } } else if (i == enums.size() - 1) { //on the last iteration for (Object o : enumsConstants) { msg[i] = ", " + o.toString() + " }"; System.out.println(Arrays.toString(msg)); } } else { //middle iteration for (Object o : enumsConstants) { msg[i] = ", " + o.toString(); printAll(enums, i + 1, msg); } } } 

Would you use it like that

 printAll(allMyEnumClassesList, 0, null); 
-1
source

Source: https://habr.com/ru/post/986381/


All Articles