检查过滤器找到任何项目并获得第一项

时间:2018-06-04 15:24:58

标签: java java-stream

我想检查filterStream找到的是否有任何内容,如果找到则返回第一项。我试过这个:

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:stream已经被操作或关闭

2 个答案:

答案 0 :(得分:2)

使用findFirstifPresent

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"));

答案 1 :(得分:1)

尝试一下,

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

创建后,您无法重复使用该流。这就是你得到这个错误的原因。您首先重新使用流并调用终端操作res.anyMatch(i -> true),然后调用另一个终端操作res.findFirst()导致此错误。这是一个反模式,应该避免。

只应对一个Stream进行操作(调用中间或终端流操作)。如果Stream实现检测到Stream正在被重用,则它可能会抛出IllegalStateException

<强>更新

根据以下评论,这可以进一步简化为,

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