来自Guava或Java枚举的ImmutableSet

时间:2013-04-11 14:57:20

标签: java enums guava

我读了here一个关于使用Guava的ImmutableSet的好例子。为了完整起见,此处报告了此示例:

public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
  "red",
  "orange",
  "yellow",
  "green",
  "blue",
  "purple");

class Foo {
  Set<Bar> bars;
  Foo(Set<Bar> bars) {
    this.bars = ImmutableSet.copyOf(bars); // defensive copy!
  }
}

问题是,我可以使用Java枚举获得相同的结果吗?

PS:This question让我心中更加混乱!

3 个答案:

答案 0 :(得分:9)

  

我可以使用Java枚举获得相同的结果吗?

是的,你可以。你试过吗?

仅供参考我还有ImmutableSet的专用版本,其中包含枚举的常量 - Sets.immutableEnumSet(在内部使用EnumSet)。

一些例子(解释Wiki的例子):

public class Test {

  enum Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE;
  }

  static class Baz {
    ImmutableSet<Color> colors;

    Baz(Set<Color> colors) {
      this.colors = Sets.immutableEnumSet(colors); // preserves enum constants 
                                                   // order, not insertion order!
    }
  }

  public static void main(String[] args) {
    ImmutableSet<Color> colorsInInsertionOrder = ImmutableSet.of(
        Color.GREEN, Color.YELLOW, Color.RED);
    System.out.println(colorsInInsertionOrder); // [GREEN, YELLOW, RED]
    Baz baz = new Baz(colorsInInsertionOrder);
    System.out.println(baz.colors); // [RED, YELLOW, GREEN]
  }
}

编辑(OP评论后):

你想在ImmutableSet中使用所有枚举常量吗?只是做:

Sets.immutableEnumSet(EnumSet.allOf(Color.class));

答案 1 :(得分:1)

不,不完全。比较

public enum Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE;
}

Set<Color> colors = EnumSet.allOf(Color.class);

Set<String> colors = ImmutableSet.of(
  "red", "orange", "yellow", "green", "blue", "purple"
);

由于Java是静态类型的,因此第一个示例中将为Set<Color>,后一示例中为Set<String>

修改1

另一个区别是你可以在运行时创建任意大小的ImmutableSet(前提是没有单个元素equals()任何其他元素)。相反,在运行时也可以创建EnumSet,但它永远不会包含比枚举值的数量更多的元素。

修改2

ImmutableSet可以包含不同类的元素,只要它们实现相同的接口即可。 EnumSet只能包含枚举类型。

答案 2 :(得分:0)

如果您没有将所有这些花哨的实用程序库作为依赖项,则可以使用标准方法:

enum Furniture{SOFA, CHAIR, TABLE};
Set<Furniture> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(Furniture.values())));
顺便说一下:这不是最有效的方式吗?我在这些库的方法中看到了很多代码,可能它有点矫枉过正?无论如何,这取决于背景。我的方法有点冗长,不做缓存等优化,但它是独立的,正是OP所要求的。