Reputation: 14243
I want to check if anything found by filter
on Stream
and if found return the first item. I have tried this:
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());
but it give me following error:
java.lang.IllegalStateException: stream has already been operated upon or closed
Upvotes: 1
Views: 112
Reputation: 21124
try this out,
final String firstMatch = Stream.of("a1", "a2", "b1", "c2", "c1")
.filter(s -> s.startsWith("c"))
.findFirst()
.orElse(null);
You can't reuse the stream once it is created. That's why you are getting that error. You first reuse the stream and call a terminal operation res.anyMatch(i -> true)
and then another terminal operation res.findFirst()
leading this error. This is an antipattern and should be avoided.
A Stream should be operated on (invoking an intermediate or terminal stream operation) only once. A Stream implementation may throw IllegalStateException
if it detects that the Stream is being reused.
Update
As per the below comment, this can further be simplified as,
Stream.of("a1", "a2", "b1", "c2", "c1").filter(s -> s.startsWith("c")).findFirst()
.ifPresent(System.out::println);
Upvotes: 1
Reputation: 56423
Use findFirst
and ifPresent
:
Stream.of("a1", "a2", "b1", "c2", "c1")
.filter(s -> s.startsWith("c"))
.findFirst()
.ifPresent(System.out::println);
or if you want to perform another operation if findFirst()
returns an empty Optional<T>
then use
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");};
or as of JDK9-
Stream.of("a1", "a2", "b1", "c2", "c1")
.filter(s -> s.startsWith("c"))
.findFirst()
.ifPresentOrElse(System.out::println, () -> System.out.println("nothing found"));
Upvotes: 2