Majid
Majid

Reputation: 14243

Check filter found any item and get first item

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

Answers (2)

Ravindra Ranwala
Ravindra Ranwala

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

Ousmane D.
Ousmane D.

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

Related Questions