java - 使用 Java 8 Stream API 查找枚举值

标签 java enums functional-programming java-8 java-stream

假设有一个名为 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/

相关文章:

java - Spring + hibernate : could not initialize proxy no Session - What to do when an exception occured on a DAO?

Java正则表达式检查字符串是否是有效的数字格式(逗号和小数点放置)

python - 将多个函数映射到键的字典 - Python

functional-programming - 函数式语言的程序是否更容易出现堆栈溢出?

functional-programming - 编写方案函数,在给定要搜索的字符的情况下,将列表中的元素加倍

java - 映射 Servlet 参数

java - 强制 JScrollPane 滚动 (X) 像素

c# - 为什么这个枚举声明现在起作用了?

具有逻辑或选择的 Java ENUM

DLL 中的 C++ FindProcessWindow