两个或多个枚举中的所有元素集

时间:2016-05-27 18:20:46

标签: java enums set

假设我们有两个或多个枚举和一个包含所有枚举元素的Set,例如:

import java.util.Map;
import java.util.Set;
import java.util.HashSet;

public class Foo {

    interface FooEnum {}

    enum FooEnum1 implements FooEnum {
        K1,
        K2
    }

    enum FooEnum2 implements FooEnum {
        K3,
        K4
    }


    static public Set<FooEnum> all = new HashSet<FooEnum>();

    public static void main(String [] args) {
      Foo it = new Foo();

      it.all.add( FooEnum1.K1 );
      it.all.add( FooEnum1.K2 );
      it.all.add( FooEnum2.K3 );
      it.all.add( FooEnum2.K4 );

      for( FooEnum k : it.all ) {
        System.out.println( k.toString() );
      }
    }
}

可以为每个集合填充all集合而没有一个“add”每个枚举的NOR A LOOP(在枚举本身之外)?也就是说,在枚举构造函数或静态代码中填写它?

**附录**

换句话说,目标是添加一个枚举元素或添加一个实现FooEnum的新枚举不需要新的代码行来填充集合(程序员可能会忘记导致错误)。

更好的是,如果在构造函数或静态代码中完成“add”的初始化。

**附录2 **

以下代码类似于预期,但不会产生预期结果:

import java.util.Map;
import java.util.Set;
import java.util.HashSet;

public class Foo {

    interface FooEnum {
    }

    static public Set<FooEnum> all = new HashSet<FooEnum>();

    enum FooEnum1 implements FooEnum {
        K1,
        K2;

    FooEnum1() {
        all.add(this);
    }
    }

    enum FooEnum2 implements FooEnum {
        K3,
        K4;

    FooEnum2() {
        all.add(this);
    }
    }



    public static void main(String [] args) {
      Foo it = new Foo();

      for( FooEnum k : it.all ) {
        System.out.println( k.toString() );
      }
    }
}

以下一个也失败了:

import java.util.Map;
import java.util.Set;
import java.util.HashSet;

public class Foo {

    interface FooEnum {
    }

    enum FooEnum1 implements FooEnum {
        K1,
        K2;

      static {
        for( FooEnum1 e : FooEnum1.values() ) {
            all.add(e);
        }
      }
    }

    enum FooEnum2 implements FooEnum {
        K3,
        K4;

      static {
        for( FooEnum2 e : FooEnum2.values() ) {
            all.add(e);
        }
      }
    }


    static public Set<FooEnum> all = new HashSet<FooEnum>();

    public static void main(String [] args) {
      Foo it = new Foo();

      for( FooEnum k : Foo.all ) {
        System.out.println( k.toString() );
      }
    }
}

3 个答案:

答案 0 :(得分:6)

您可能想要使用Set#addAll(Collection)。它会自动将所有枚举值添加到HashSet

it.all.addAll(Arrays.asList(FooEnum1.values()));
it.all.addAll(Arrays.asList(FooEnum2.values()));

如果您正在使用,则此处是oneliner。

  it.all.addAll(Stream.of(FooEnum1.values(), FooEnum2.values())
                      .flatMap(x -> Arrays.stream(x)).collect(Collectors.toSet()));

你可能无法获得可读性,但它是一个oneliner。

答案 1 :(得分:6)

使用thing.__radd__("asdf")似乎是解决此问题的一种相对简单的方法:

EnumSet#allOf

答案 2 :(得分:1)

您也可以在一行中完成:

Stream.<FooEnum[]>of(FooEnum1.values(), FooEnum2.values())
    .map(Arrays::asList).forEach(it.all::addAll);

更具异国情调的方法:

static public Set<FooEnum> all = new HashSet<FooEnum>();

interface FooEnum {
    default void register() { // you can name this method however you want
        all.add(this);
    }
}

enum FooEnum1 implements FooEnum {
    K1,
    K2;

    FooEnum1() {
        register();
    }
}

enum FooEnum2 implements FooEnum {
    K3,
    K4;

    FooEnum2() {
        register();
    }
}

这种方法的优点是可以将集合与枚举类解耦 - 只有接口知道集合。你必须在enum的构造函数中编写对register()的调用,但这就是全部。每个实例都将“自动”添加到集合中。