当前位置: 首页 > 知识库问答 >
问题:

使用Java 8流API查找枚举值

宁侯林
2023-03-14

假设有一个名为 Type 的简单枚举,定义如下:

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

    private String s;

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

为给定的<code>s</code>找到正确的枚举是用带有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是多余的和令人困惑的。然而,我在流API中找不到任何东西,只是以某种方式直接从流返回T

有更好的方法吗?


共有3个答案

班经亘
2023-03-14
Arrays.stream(Type.values()).filter(v -> v.s.equals(val)).findAny().orElseThrow(...);
濮阳鸿祯
2023-03-14

公认的答案效果很好,但是如果您想避免使用临时数组创建新流,您可以使用EnumSet.allOf()

EnumSet.allOf(Type.class)
       .stream()
       .filter(e -> e.s.equals(val))
       .findFirst()
       .orElseThrow(() -> new IllegalStateException(String.format("Unsupported type %s.", val)));
钱振
2023-03-14
匿名用户

我会使用< code>findFirst来代替:

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;
    }
}

我从这个答案中学到了这个技巧。基本上,类装入器在枚举类之前初始化静态类,这允许您在枚举构造函数本身中填充Map。非常方便!

希望有帮助!:)

 类似资料:
  • 我有一个,另一个作为参数 我想创建一个按类型返回的方法 通常我会写 用java stream写的最佳做法是什么?

  • 问题内容: 假设有一个名为Type的简单枚举定义如下: 找到具有给定值的正确枚举通常是通过带for循环的静态方法(假设该方法在枚举内部定义)完成的,例如: 我认为用Stream API表示的功能等效如下: 我们怎么能写得更好,更简单?这段代码让人感觉很强迫,而且不太清楚。该特别是似乎笨重和滥用,因为它不累积什么,不进行计算,并始终直接返回(提供过滤器返回一个值- 如果不说的显然是个灾难),更何况是

  • 假设我有一个枚举: 如果我有一个数字,我可以这样得到枚举键: 然而,这给了我一个字符串。我怎样才能得到一个Color类型的变量呢?即:

  • 枚举定义- 存储库- 服务电话- 例外情况- 为什么它会抛出此异常?我已经定义了@Enumerated(EnumType.STRING),所以它应该期望存储在db中的字符串类型。

  • 我有以下枚举: 我想用和null值中的键创建映射。我试着按照这个答案下面的代码: 但我在这里得到的是。我做错了什么?