【发布时间】:2015-03-04 15:01:31
【问题描述】:
假设有一个名为 Type 的简单枚举定义如下:
enum Type{
X("S1"),
Y("S2");
private String s;
private Type(String s) {
this.s = s;
}
}
为给定的s 找到正确的枚举可以使用带有 for 循环的静态方法轻松完成(假设该方法是在枚举中定义的),例如:
private static Type find(String val) {
for (Type e : Type.values()) {
if (e.s.equals(val))
return e;
}
throw new IllegalStateException(String.format("Unsupported type %s.", val));
}
我认为用 Stream API 表达的功能等价物是这样的:
private static Type find(String val) {
return Arrays.stream(Type.values())
.filter(e -> e.s.equals(val))
.reduce((t1, t2) -> t1)
.orElseThrow(() -> {throw new IllegalStateException(String.format("Unsupported type %s.", val));});
}
我们怎样才能写得更好更简单?这段代码感觉是强制的,不是很清楚。 reduce() 尤其显得笨重和滥用,因为它不累积任何东西,不执行任何计算,并且总是简单地返回 t1(如果过滤器返回一个值 - 如果它不返回一个值,那显然是一场灾难),更不用说 @ 987654327@是不是有多余的和混乱的。然而,我在 Stream API 中找不到任何东西,它只是以某种方式从 Stream<T> 直接返回 T。
有没有更好的办法?
【问题讨论】:
-
我知道这条评论不会被任何人赞成,但与 Java 8 一样伟大的是,您不必为每个问题都使用
Streams。您的 for 循环方法比使用Streams 的任何方法都更清晰(更快)。 -
@pbabcdefp 好吧,我认为这是一个很好的评论,但是如果我赞成,那么您评论中的第一句话就是错误的,这意味着我必须再次反对,然后我会再次认为这是一个很好的评论,所以我不得不赞成它,但是第一句话是错误的......我想我要抛出
StackOverflowException...... -
@pbabcdefp - 这可能是一个见仁见智的问题,但我发现 lambda 越来越优于迭代,而且清晰度几乎总是胜过效率。我很肯定我已经尝试过
findFirst()并且在 IDEA 中遇到了一些奇怪的编译错误并编写了reduce()变体。无论如何,我对你所有的答案都投了赞成票,但觉得first比any更清楚,所以我同意了。感谢您的帮助!
标签: java enums functional-programming java-8 java-stream