-1

I have following code which uses Stream API to find names of first 3 elements in a collection which have calories more than 300:

List<Dish> dishes = ....
List<String> unhealthyDishes = dishes.stream()
                                     .filter(dish -> dish.getCalories() > 300)
                                     .map(dish -> dish.getName())
                                     .limit(3)
                                     .collect(Collectors.toList());

In traditional iterator based imperative approach, I can keep count of the results and hence exit the iteration loop once I have got required number of elements. But above code seems to go through the entire length of the collection. How can I stop it doing so and stop once I have got 3 elements I need?

Mandroid
  • 6,200
  • 12
  • 64
  • 134
  • Does this answer your question? [terminate or break java 8 stream loop](https://stackoverflow.com/questions/23996454/terminate-or-break-java-8-stream-loop) – Hrudayanath Jul 26 '20 at 10:15
  • 1
    [`Stream.limit`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/Stream.html#limit(long)) is a [short-circuiting stateful intermediate operation.](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/package-summary.html#StreamOps) – Naman Jul 26 '20 at 10:25
  • 1
    What's wrong with the question to deserve a downvote? – Mandroid Jul 26 '20 at 10:27

1 Answers1

1

How do you know it checks the other elements as well? I just set up this small test:

String[] words = {"a", "a", "a", "aa"};
        
List<Integer> shortWords = Arrays.stream(words)
     .filter(word -> {
             System.out.println("checking " + word);
             return word.length() == 1;
             })
     .map(String::length)
     .limit(3)
     .collect(Collectors.toList());
        
System.out.println(shortWords);

And the output was:

checking a
checking a
checking a
[1, 1, 1]
tdranv
  • 1,140
  • 11
  • 38