假设有一个名为 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
(假设过滤器返回一个值 - 如果它没有,那显然是一场灾难),更不用说 t2
是否有多余和困惑。然而,我在 Stream API 中找不到任何直接返回 T
的东西。来自 Stream<T>
.
有没有更好的办法?
最佳答案
我会使用 findFirst
代替:
return Arrays.stream(Type.values())
.filter(e -> e.s.equals(val))
.findFirst()
.orElseThrow(() -> new IllegalStateException(String.format("Unsupported type %s.", val)));
虽然在这种情况下
Map
可能会更好:
enum Type{
X("S1"),
Y("S2");
private static class Holder {
static Map<String, Type> MAP = new HashMap<>();
}
private Type(String s) {
Holder.MAP.put(s, this);
}
public static Type find(String val) {
Type t = Holder.MAP.get(val);
if(t == null) {
throw new IllegalStateException(String.format("Unsupported type %s.", val));
}
return t;
}
}
我从 answer 中学到了这个技巧.基本上,类加载器在枚举类之前初始化静态类,这允许您在枚举构造函数本身中填充 Map
。很方便!
希望对您有所帮助! :)
关于java - 使用 Java 8 Stream API 查找枚举值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27807232/