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

Java 两个或多个枚举中所有元素的集合,java,enums,set,java-8,Java,Enums,Set,Java 8,假设我们有两个或多个枚举和一个包含所有枚举元素的集合,如: 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 FooEn

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

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() );
      }
    }
}
以下一项也失败了:

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() );
      }
    }
}
import java.util.Map;
导入java.util.Set;
导入java.util.HashSet;
公开课Foo{
接口FooEnum{
}
枚举FooEnum1实现FooEnum{
K1,
K2;
静止的{
对于(FooEnum1 e:FooEnum1.values()){
全部。添加(e);
}
}
}
枚举FooEnum2实现FooEnum{
K3,
K4;
静止的{
对于(FooEnum2 e:FooEnum2.values()){
全部。添加(e);
}
}
}
静态公共集all=newhashset();
公共静态void main(字符串[]args){
Foo it=新的Foo();
for(FooEnum k:Foo.all){
System.out.println(k.toString());
}
}
}

您可能需要使用
Set#addAll(集合)
。它将自动将所有枚举值添加到
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()));

您可能无法获得可读性,但它是一个单行程序。

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

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

如果您正在使用,这里有一个oneliner

  it.all.addAll(Stream.of(FooEnum1.values(), FooEnum2.values())
                      .flatMap(x -> Arrays.stream(x)).collect(Collectors.toSet()));
您可能无法获得可读性,但它是一个单行程序。

使用
EnumSet#allOf
似乎是解决此问题的相对简单的方法:

  it.all.addAll(Stream.of(FooEnum1.values(), FooEnum2.values())
                      .flatMap(x -> Arrays.stream(x)).collect(Collectors.toSet()));
it.all.addAll(EnumSet.allOf(FooEnum1.class));
it.all.addAll(EnumSet.allOf(FooEnum2.class));
使用
EnumSet#allOf
似乎是解决这一问题的相对简单的方法:

it.all.addAll(EnumSet.allOf(FooEnum1.class));
it.all.addAll(EnumSet.allOf(FooEnum2.class));

您也可以在一行中完成:

Stream.<FooEnum[]>of(FooEnum1.values(), FooEnum2.values())
    .map(Arrays::asList).forEach(it.all::addAll);
Stream.of(FooEnum1.values(),FooEnum2.values())
.map(数组::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();
    }
}
static public Set all=new HashSet();
接口FooEnum{
默认的void register(){//您可以随意命名此方法
全部。添加(此);
}
}
枚举FooEnum1实现FooEnum{
K1,
K2;
FooEnum1(){
寄存器();
}
}
枚举FooEnum2实现FooEnum{
K3,
K4;
FooEnum2(){
寄存器();
}
}

这种方法的优点是将集合与枚举类解耦——只有接口知道集合。您确实需要在枚举的构造函数中编写对
register()
的调用代码,但仅此而已。每个实例都将“自动”添加到集合中。

您也可以在一行中完成:

Stream.<FooEnum[]>of(FooEnum1.values(), FooEnum2.values())
    .map(Arrays::asList).forEach(it.all::addAll);
Stream.of(FooEnum1.values(),FooEnum2.values())
.map(数组::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();
    }
}
static public Set all=new HashSet();
接口FooEnum{
默认的void register(){//您可以随意命名此方法
全部。添加(此);
}
}
枚举FooEnum1实现FooEnum{
K1,
K2;
FooEnum1(){
寄存器();
}
}
枚举FooEnum2实现FooEnum{
K3,
K4;
FooEnum2(){
寄存器();
}
}


这种方法的优点是将集合与枚举类解耦——只有接口知道集合。您确实需要在枚举的构造函数中编写对
register()
的调用代码,但仅此而已。每个实例都将“自动”添加到集合中。

谢谢您的回答。但是,正在寻找一种解决方案,该解决方案不需要为每个枚举指定一行。问题澄清了。嗯,我完全忘记了
values()
。我今天的票数没有了,不幸的是,我明天回到这里投票。@Mureinik谢谢:)我想两个答案都可以。我当然比你高。@pasabaporaqui这是一个单行解决方案。@Mureinik:是的,这是一个单行解决方案,但该行仍然同时包含FooEnum1和FooEnum2。如果有人使用了新的“FooEnum3”,但忘记更改此行,则会发生错误。感谢您的回答。但是,正在寻找一种解决方案,该解决方案不需要为每个枚举指定一行。问题澄清了。嗯,我完全忘记了
values()
。我今天的票数没有了,不幸的是,我明天回到这里投票。@Mureinik谢谢:)我想两个答案都可以。我当然比你高。@pasabaporaqui这是一个单行解决方案。@Mureinik:是的,这是一个单行解决方案,但该行仍然同时包含FooEnum1和FooEnum2。如果有人使用了新的“FooEnum3”,但忘记更改此行,则会发生错误。感谢您的回答。但是,正在寻找一种解决方案,该解决方案不需要为每个枚举指定一行。问题澄清。@Tom:如果我的解释不够的话,很抱歉。答案包含两个语句,一个用于“FooEnum1”,另一个用于“FooEnum2”。如果程序员添加了一个新的“FooEnum3”,但忘记添加一个新的行,就像答案中的行一样,那么我们就有一个错误。我想猜测这种可能性。@pasabaporaqui问题是,这段代码不知道要添加哪些枚举,因为它不知道存在哪些枚举。您可能希望找到实现
FooEnum
(like)的每个枚举,但生成的代码可能不清楚/难以理解。@Tom:原始问题的新附录已经编写,希望澄清。谢谢您的回答。但是,正在寻找一种解决方案,该解决方案不需要为每个枚举指定一行。问题澄清。@Tom:如果我的解释不够的话,很抱歉。答案包含两个语句,一个用于“FooEnum1”,另一个用于“FooEnum2”。如果程序员添加了一个新的“FooEnum3”,但忘记添加一个新的行,就像答案中的行一样,那么我们就有一个错误。我想猜测这种可能性。@pasabaporaqui问题是,这段代码不知道要添加哪些枚举,因为它不知道存在哪些枚举。您可能希望找到实现
FooEnum
(like)的每个枚举,但生成的代码可能不清楚/难以理解。@Tom:原始问题的新附录已经编写,希望澄清。感谢您的回答,但是,该语句包含“FooEnum1”和“FooEnum2”。寻找一个解决方案,而不必担心。请参阅问题澄清。@pasa要做到这一点,您必须能够回答“什么类实现了F?”