枚举返回数组流

时间:2018-07-19 06:45:51

标签: java enums java-8 java-stream

我需要根据一些预定义的值(将来可能会增加)来验证字段。为此,我创建了一个Enum并定义了一个返回允许值流的方法。

public enum EnumDemo {

    VERSION("1.0.0","2.0.3");

    private List<String> ver;

    EnumDemo(String... ver) {
        this.ver = Arrays.asList(ver);
    }

    public List<String> getVer() {
        return ver;
    }

    public static Stream<EnumDemo> stream() {
        return Arrays.stream(EnumDemo.values());
    }
}

现在,我需要对照此枚举中定义的值来验证字段。

我正在使用:

Optional<EnumDemo> ab = EnumDemo.stream()
.map(l -> {l.getVer().stream()
                     .filter(c -> c.equals("2.0.3"))
                     .findFirst();})
.findFirst();

System.out.println(ab.get().getVer());

但是它给了我编译错误。任何帮助将不胜感激。

编辑:

编译错误:

The method map(Function<? super EnumDemo,? extends R>) in the type Stream<EnumDemo> is not applicable for the arguments ((<no type> l) -> {})

3 个答案:

答案 0 :(得分:4)

您应该这样写:

Optional<EnumDemo> ab = EnumDemo.stream().filter(l -> l.getVer().contains("2.0.3"))
                                         .findFirst();

顺便说一句,它不起作用,因为您为lambda表达式使用了{},所以它期望return中有一个{}语句。您可以删除{}(以及;)或添加return

无论如何,原始代码看起来很混乱,不确定我是否正确猜到了意图,但是这种实现应该更清楚。

编辑

根据您的评论,这是您需要的:

EnumDemo.stream().flatMap(l -> l.getVer().stream())
                 .filter("2.0.3"::equals)
                 .findAny()
                 .ifPresent(System.out::println);

更新

Holger评论说,有一种更短,更有意义的方法,它具有更好的性能:

if(EnumDemo.stream()
           .anyMatch(l -> l.getVer().contains(userString))) {
    System.out.println(userString);
}

答案 1 :(得分:3)

要理解它,您必须考虑lambda。 Lambda代表interface,但是JVM对其进行了特殊处理,因此并非每个Lambda都需要一个类来表示。 (无状态lambda可以只是方法)。

现在,在map()界面中查看Stream方法时:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

您看到它期望实现Function接口。您现在可以通过多种不同方式来提供该映射器。在此示例中,将映射从Object映射到String

1。使用内联lambda:

.map(o -> o.toString())

2。使用多行lambda:

.map(o -> { 
    return o.toString(); 
})

3。使用方法引用:

.map(Object::toString)

4。使用匿名类:

.map(new Function<Object, String>(){
     @Override
     public String apply(Object o){
         return o.toString();
     }
})

您当前的代码使用 2。方法。但是没有return语句。在 4。上查看匿名类时,这一点甚至更好。很自然,当在不返回任何值的方法中不使用return语句时。

  

这就是为什么会出现编译错误。

您只需要添加return语句:

.map(l -> {
    return l.getVer().stream()
        .filter(c -> c.equals("2.0.3"))
        .findFirst();
});

或卸下括号{}

.map(l -> l.getVer().stream()
    .filter(c -> c.equals("2.0.3"))
    .findFirst());

或者甚至使用@Jai在his answer中提供的方法。比您目前拥有的更好。

答案 2 :(得分:2)

您正在使用lambda表达式,并且没有返回任何值,因此它给出了编译错误。最好使用ifPresent()

String val="2.0.3";
EnumDemo.stream()
    .flatMap(l -> l.getVer().stream())
    .filter(c -> c.equals(val))
    .findAny()
    .ifPresent(x -> System.out.println(x));