Java 8的方式与枚举工作

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)

我想知道在Java 8中处理枚举的所有值的最佳方式。特别是当您需要获取所有值并将其添加到某处时,例如,假设我们有以下枚举:

public enum Letter {
 A, B, C, D;
}

我当然可以做到以下几点:

for (Letter l : Letter.values()) {
    foo(l);
}

但是,我也可以将以下方法添加到枚举定义中:

public static Stream<Letter> stream() {
    return Arrays.stream(Letter.values());
}

然后从上面替换为:

Letter.stream().forEach(l -> foo(l));

这种方法是否行得通,或者在设计或性能方面有问题?此外,为什么不枚举有一个stream()方法?

提问于
用户回答回答于

三个问题:三部分答案:

从设计的角度来看可以吗?

绝对。它没有错。如果你需要对你的枚举进行大量的迭代,那么流API是一个干净的方法,并且将隐藏在一个小方法后面的锅炉板很好。尽管我认为OldCumudgeon版本更好。

从性能的角度来看,它可以吗?

这很可能没有关系。大多数情况下,枚举不是那么大。因此,在99.9%的情况下,无论是哪种方法或某种方法的开销可能都无关紧要。

当然,它有0.1%的地方。在这种情况下:用您的真实世界的数据和消费者进行适当的衡量。

如果我必须打赌,我预计for each循环会更快,因为它更直接映射到内存模型,但不要在谈论性能时猜测,并且在实际需要调整之前不要调整。以首先正确的方式编写代码,易于阅读,然后才担心代码风格的性能。

为什么Enums没有正确集成到Stream API中?

如果您将Java的Stream API与许多其他语言的等效语言进行比较,则它显得非常有限。有多种片段丢失(例如,可重复使用的Streams和Optionals作为Streams)。另一方面,实现Stream API对API来说无疑是一个巨大的改变。由于某种原因,它被推迟了多次。所以我猜想Oracle希望将这些更改限制在最重要的用例中。无论如何,枚举不会被使用太多。当然,每个项目都有其中的一些,但与列表和其他集合的数量相比,它们没有任何区别。即使你有一个枚举,在很多情况下你都不会重复它。另一方面,列表和集合几乎每次都可能迭代。我认为这些就是为什么Enums没有自己的适配器到Stream世界的原因。我们将看看更多这些是否会在未来的版本中添加。在那之前你总是可以使用Arrays.stream.

用户回答回答于

我会去的EnumSet。因为forEach()也被定义Iterable,所以你可以避免完全创建流:

EnumSet.allOf(Letter.class).forEach(x -> foo(x));

或者用方法参考:

EnumSet.allOf(Letter.class).forEach(this::foo);

尽管如此,oldschool for-loop感觉更简单一些:

for (Letter x : Letter.values()) {
    foo(x);
}

扫码关注云+社区