title: Should I stream multiple times or do all calculations in one stream?
body: <p>I have the following code:</p>
  
  <pre><code>mostRecentMessageSentDate = messageInfoList
      .stream()
      .findFirst().orElse(new MessageInfo())
      .getSentDate();
  
  unprocessedMessagesCount = messageInfoList
      .stream()
      .filter(messageInfo -&gt; messageInfo.getProcessedDate() == null)
      .count();
  
  hasAttachment = messageInfoList
      .stream()
      .anyMatch(messageInfo -&gt; messageInfo.getAttachmentCount() &gt; 0);
  </code></pre>
  
  <p>As you can see, I stream the same list 3 times, because I want to find 3 different values. If I did this in a For-Each loop, I could loop just once. </p>
  
  <p>Is it better, performance wise to do this a for loop then, so that I loop only once? I find the streams much more readable.</p>
  
  <p>Edit: I ran some tests:</p>
  
  <pre><code>import java.util.List;
  import java.util.stream.Collectors;
  import java.util.stream.IntStream;
  
  public class Main {
  
  public static void main(String[] args) {
  
      List&lt;Integer&gt; integerList = populateList();
  
      System.out.println("Stream time: " + timeStream(integerList));
      System.out.println("Loop time: " + timeLoop(integerList));
  
  }
  
  private static List&lt;Integer&gt; populateList() {
      return IntStream.range(0, 10000000)
              .boxed()
              .collect(Collectors.toList());
  }
  
  private static long timeStream(List&lt;Integer&gt; integerList) {
      long start = System.currentTimeMillis();
  
      Integer first = integerList
              .stream()
              .findFirst().orElse(0);
  
      long containsNumbersGreaterThan10000 = integerList
              .stream()
              .filter(i -&gt; i &gt; 10000)
              .count();
  
      boolean has10000 = integerList
              .stream()
              .anyMatch(i -&gt; i == 10000);
  
      long end = System.currentTimeMillis();
  
      System.out.println("first: " + first);
      System.out.println("containsNumbersGreaterThan10000: " + containsNumbersGreaterThan10000);
      System.out.println("has10000: " + has10000);
  
      return end - start;
  }
  
  private static long timeLoop(List&lt;Integer&gt; integerList) {
      long start = System.currentTimeMillis();
  
      Integer first = 0;
      boolean has10000 = false;
      int count = 0;
      long containsNumbersGreaterThan10000 = 0L;
      for (Integer i : integerList) {
          if (count == 0) {
              first = i;
          }
  
          if (i &gt; 10000) {
              containsNumbersGreaterThan10000++;
          }
  
          if (!has10000 &amp;&amp; i == 10000) {
              has10000 = true;
          }
  
          count++;
      }
  
      long end = System.currentTimeMillis();
  
      System.out.println("first: " + first);
      System.out.println("containsNumbersGreaterThan10000: " + containsNumbersGreaterThan10000);
      System.out.println("has10000: " + has10000);
  
      return end - start;
  }
  }
  </code></pre>
  
  <p>and as expected, the for loop is always faster than the streams</p>
  
  <pre><code>first: 0
  containsNumbersGreaterThan10000: 9989999
  has10000: true
  Stream time: 57
  first: 0
  containsNumbersGreaterThan10000: 9989999
  has10000: true
  Loop time: 38
  </code></pre>
  
  <p>But never significantly. </p>
  
  <p>The findFirst was probably a bad example, because it just quits if the stream is empty, but I wanted to know if it made a difference.</p>
  
  <p>I was hoping to get a solution that allowed multiple calculations from one stream. IntSummaryStatistics dont do exactly what I want. I think I'll heed @florian-schaetz and stick to favouring readbility for a marginal performance increase</p>