找到所有可能的枚举组合

时间:2015-05-01 19:17:34

标签: java java-7 java-collections-api

是否有一种有效的方法可以在Java中找到多个枚举之间的所有可能组合?

考虑以下三个枚举 -

public enum EnumOne {
   One ("One"),
   OneMore ("OneMore");
}

public enum EnumTwo {
   Two ("Two"),
}

public enum EnumThree {
   Three ("Three"),
   ThreeMore ("ThreeMore");
}

我希望输出产生这些多个枚举之间的所有可能组合,即

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

希望找到一种有效的方法来处理它。

由于

2 个答案:

答案 0 :(得分:0)

这是一个基于迭代器的解决方案。这样,如果内存消耗在具有枚举常量负载的许多枚举类型上运行,则内存消耗不会爆炸。因此执行效率应该很好(此外,实现避免了递归)。

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可以像这样使用:

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));
        }
    }
}

但是,当然,人们也可以使用番石榴cartesianProduct() ......

答案 1 :(得分:-1)

这样的事情怎么样。

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);
        }
    }
}

你会像这样使用它

printAll(allMyEnumClassesList, 0, null);