使用Java 8 Stream API查找枚举值 [英] Finding enum value with Java 8 Stream API

查看:1360
本文介绍了使用Java 8 Stream API查找枚举值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有一个简单的枚举类型定义如下:

Suppose there is a simple enum called Type defined like this:

enum Type{
    X("S1"),
    Y("S2");

    private String s;

    private Type(String s) {
        this.s = s;
    }
}

找到正确的枚举给定 s 使用静态方法与for循环(假设该方法在枚举中定义),例如:

Finding the correct enum for given s is trivially done with static method with for-loop (assume the method is defined inside enum), e.g.:

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表达的功能等同物将是这样的:

I think the functional equivalent of this expressed with Stream API would be something like this:

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中找不到任何东西,只是以某种方式直接从 Stream< T> 中直接返回一个 T

How could we write this better and simpler? This code feels coerced and not very clear. The reduce() especially seems clunky and abused as it doesn't accumulate anything, performs no calculation and always simply returns t1 (provided the filter returns one value - if it doesn't that's clearly a disaster), not to mention t2 is there superfluous and confusing. Yet I couldn't find anything in Stream API that simply somehow returns directly a T from a Stream<T>.

有没有更好的方法?

推荐答案

code> findFirst 代替:

I would use findFirst instead:

return Arrays.stream(Type.values())
            .filter(e -> e.s.equals(val))
            .findFirst()
            .orElseThrow(() -> new IllegalStateException(String.format("Unsupported type %s.", val)));



虽然地图可能会更好:

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 。非常方便!

I learnt this trick from this answer. Basically the class loader initializes the static classes before the enum class, which allows you to fill the Map in the enum constructor itself. Very handy !

希望它有帮助! :)

这篇关于使用Java 8 Stream API查找枚举值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆