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

检查筛选器找到任何项并获取第一项

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

    我想查一下 filter Stream 如果找到了,返回第一个项目。我试过这个:

    Stream<String> res= Stream.of("a1", "a2", "b1", "c2", "c1")
    .filter(s -> s.startsWith("c"));
    
    if(res.anyMatch(i->true))
         System.out.println(res.findFirst().get());
    

    但它给了我以下错误:

    java.lang.IllegalStateException:流已被操作或关闭

    2 回复  |  直到 6 年前
        1
  •  1
  •   Ravindra Ranwala    6 年前

    试试这个,

    final String firstMatch = Stream.of("a1", "a2", "b1", "c2", "c1")
                                    .filter(s -> s.startsWith("c"))
                                    .findFirst()
                                    .orElse(null);
    

    一旦创建流,就不能重用它。这就是为什么你会犯这个错误。首先重用流并调用终端操作 res.anyMatch(i -> true) 然后是另一个终端操作 res.findFirst() 导致此错误。这是一个反模式,应该避免。

    一个流只能操作一次(调用中间或终端流操作)。流实现可能抛出 IllegalStateException 如果它检测到流正在被重用。

    更新

    根据下面的评论,可以进一步简化为:

    Stream.of("a1", "a2", "b1", "c2", "c1").filter(s -> s.startsWith("c")).findFirst()
                    .ifPresent(System.out::println);
    
        2
  •  2
  •   Ousmane D.    6 年前

    使用 findFirst ifPresent :

    Stream.of("a1", "a2", "b1", "c2", "c1")
          .filter(s -> s.startsWith("c"))
          .findFirst()
          .ifPresent(System.out::println);
    

    或者如果您想执行另一个操作,如果 findFirst() 返回空值 Optional<T> 然后使用

    Optional<String> result =
        Stream.of("a1", "a2", "b1", "c2", "c1")
              .filter(s -> s.startsWith("c"))
              .findFirst();
    if(result.isPresent()){ System.out.println(result.get());}
    else{ System.out.println("nothing found");};
    

    或从JDK9开始-

     Stream.of("a1", "a2", "b1", "c2", "c1")
           .filter(s -> s.startsWith("c"))
           .findFirst()
           .ifPresentOrElse(System.out::println, () -> System.out.println("nothing found"));