关闭。这个问题是基于意见的。它目前不接受答案。
**想改进这个问题吗?**更新这个问题,这样就可以通过编辑这篇文章用事实和引文来回答。
两年前关门了。
改进这个问题
我想知道在Java8中处理枚举的所有值的最佳方法是什么。特别是当您需要获取所有值并将其添加到某个位置时,例如,假设我们有以下枚举:
public enum Letter {
A, B, C, D;
}
我当然可以做到以下几点:
for (Letter l : Letter.values()) {
foo(l);
}
但是,我也可以将以下方法添加到枚举定义中:
public static Stream<Letter> stream() {
return Arrays.stream(Letter.values());
}
然后将上面的for替换为:
Letter.stream().forEach(l -> foo(l));
这种方法行吗?还是在设计或性能上有缺陷?此外,为什么枚举没有stream()方法?
4条答案
按热度按时间g6ll5ycj1#
三问三答:
从设计的Angular 看可以吗?
当然。没什么问题。如果您需要对枚举进行大量迭代,那么streamapi是一种干净的方法,可以将锅炉板隐藏在一个小方法后面。尽管我认为奥德库姆登的版本更好。
从性能的Angular 看可以吗?
很可能没关系。大多数时候,枚举并没有那么大。因此,在99.9%的情况下,一种方法或另一种方法的开销可能并不重要。
当然,这其中也有0.1%。在这种情况下:用真实世界的数据和消费者进行适当的测量。
如果非要我打赌的话,我希望
for each
循环要更快,因为它更直接地Map到内存模型,但是在谈论性能时不要猜测,并且在实际需要调优之前不要调优。先以正确的方式编写代码,然后以易于阅读的方式编写代码,然后才考虑代码样式的性能。为什么枚举没有正确地集成到流api中?
如果将java的流api与许多其他语言中的等效api进行比较,就会发现它受到了严重的限制。缺少各种片段(例如,可重用流和可选流)。另一方面,实现streamapi对api来说无疑是一个巨大的变化。由于某种原因,它被多次推迟。所以我猜oracle想把更改限制在最重要的用例上。反正枚举也没用那么多。当然,每个项目都有几个,但与列表和其他集合的数量相比,它们不算什么。即使你有一个枚举,在很多情况下你永远不会迭代它。另一方面,列表和集合几乎每次都会被迭代。我假设这就是枚举没有自己的流世界适配器的原因。我们将看看未来的版本中是否会添加更多这样的内容。在那之前你可以用
Arrays.stream
.1hdlvixo2#
我会选择
EnumSet
. 因为forEach()
也定义在Iterable
,可以完全避免创建流:或使用方法引用:
尽管如此,loop的老学校还是让人感觉简单了一点:
z31licg03#
我猜枚举的大小是有限的(即大小不受语言限制,但受用法限制),因此它们不需要本机流api。流是非常好的,当你必须操纵变换和回忆的元素在一个流;这些不是枚举的常见用例(通常迭代枚举值,但很少需要转换、Map和收集它们)。
如果您只需要对每个元素执行一个操作,那么您应该只公开foreach方法
k3fezbri4#
我认为最短的代码
Stream
枚举常量的Stream.of(Letter.values())
. 没有你想象的那么好Letter.values().stream()
但这是数组的问题,而不是枚举。而且,为什么枚举没有
stream()
方法?你说得对,最好的办法是
Letter.stream()
. 不幸的是,一个类不能有两个具有相同签名的方法,因此不能隐式地添加静态方法stream()
到每个枚举(与每个枚举都有一个隐式添加的静态方法相同)values()
)因为这将破坏已经有静态或示例方法但没有调用参数的所有现有枚举stream()
.这种方法行吗?
我认为是这样。缺点是
stream
是静态方法,因此无法避免代码重复;它必须分别添加到每个枚举中。