使用Java 8 Stream API查找枚举值

假设有一个名为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从返回a

的东西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在这种情况下a 可能更好:

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;

}

}

我从这个答案中学到了这个技巧。基本上,类加载器会在枚举类之前初始化静态类,这使您可以Map将枚举构造器本身填充。非常便利

您想要一个Map<String, Code>,但是如何整齐地填充它呢?枚举不允许您在初始化枚举实例之前初始化静态字段,但是有一个巧妙的小技巧,称为“ 按需初始化holder idiom”,它使使用此功能所需的静态初始化映射变得容易实现:

public enum Code {

CODE_1("string1"),

CODE_2("string2"),

CODE_3("string3"),

// etc

;

private static class Holder {

static Map<String, Code> CODE_MAP = new HashMap<>();

}

private final String code;

private Code(String code) {

this.code = code;

Holder.CODE_MAP.put(code, this);

}

public String getCode() {

return this.code;

}

public Code convertFromString(String code) {

return CODE_MAP.get(code);

}

}

之所以可行,是因为类加载器在初始化枚举类之前先初始化内部静态类,因此将映射分配为在枚举实例初始化期间准备加载。

没有循环。无需特殊代码即可加载地图(在构造函数中完成)。最少的代码。

希望能帮助到你 !:)

以上是 使用Java 8 Stream API查找枚举值 的全部内容, 来源链接: utcz.com/qa/417743.html

回到顶部