代码之家  ›  专栏  ›  技术社区  ›  Abhishek

返回数组流的枚举

  •  1
  • Abhishek  · 技术社区  · 6 年前

    我有一个要求,根据一些预定义的值来验证一个字段(以后可能会增长)。为此,我创建了一个枚举并定义了一个返回允许值流的方法。

    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 回复  |  直到 6 年前
        1
  •  4
  •   Jai    6 年前

    你应该这样写:

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

    顺便说一下,它不起作用,因为你用过 {} 对于lambda表达式,因此它需要 return 声明 {} . 您可以移除 {} (连同 ; )或添加 返回 .

    不管怎样,最初的代码看起来很混乱,不确定我是否正确地猜测了意图,但是这个实现应该更清晰。

    编辑

    根据您的意见,这是您需要的:

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

    更新

    霍尔格评论说,有一种更短、更有意义的方法,性能更好:

    if(EnumDemo.stream()
               .anyMatch(l -> l.getVer().contains(userString))) {
        System.out.println(userString);
    }
    
        2
  •  3
  •   Lino    6 年前

    要理解这一点,你必须考虑兰伯斯。兰姆达斯代表 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(); 
    })
    

    三。使用方法引用:

    .map(Object::toString)
    

    4。使用匿名类:

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

    您当前的代码使用 2。 接近。但没有 return 声明。当看到匿名类 4。 . 当不使用 返回 方法中没有返回值的语句。

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

    您只需添加 返回 声明:

    .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 . 比你现在拥有的更好。

        3
  •  2
  •   Lino    6 年前

    您正在使用 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));