title: Why does `.hasNext()` consume elements from `BufferedReader`?
body: <p><strong>Problem statement</strong></p>
  
  <p>In a compiled <code>.jar</code> file that I execute on wsl Ubuntu, I run command: <code>task reportToGetUrgencyOfAllTasks</code> which returns a list of tasks with columns: <code>id, uuid, urgency</code>. I can inspect the list, it is printed to terminal, and it consist of 1793 tasks and 1798 lines (a header and some irrelevant messages about requiring sync.). When I count the number of objects with <code>reader.lines().count()</code> it returns 1798 and consumes the lines as expected.</p>
  
  <p>If I create a while loop with: </p>
  
  <pre><code>long counter = 0;
  while (reader.lines().iterator().hasNext()) {
      counter++;
      System.out.println("counter=" + counter);
  }
  </code></pre>
  
  <p>It lists numbers 1 to 1798, which is weird because I thought the <code>.hasNext()</code> did not consume items, but only checked whether the next element existed or not, without taking it from the stream. (As suggested here:<a href="https://hajsoftutorial.com/iterator-hasnext-and-next/" rel="nofollow noreferrer">https://hajsoftutorial.com/iterator-hasnext-and-next/</a>). I expected an infinite loop of numbers because the iterator would stay at the first element forever after the <code>hasNext()</code>.</p>
  
  <p>So then if I want to take all elements from the reader and put them into an ArrayList with:</p>
  
  <pre><code>ArrayList&lt;String&gt; capturedCommandOutput = new ArrayList&lt;String&gt;();
  while (reader.lines().iterator().hasNext()) {
      counter++;
      capturedCommandOutput.add(reader.lines().iterator().next());
  }
  </code></pre>
  
  <p>It skips every other line. </p>
  
  <p><strong>Question</strong> </p>
  
  <p>Why does <code>hasNext()</code> consume elements from the iterator in this scenario?</p>
  
  <p><strong>Complete code</strong>
  For an MWE one needs to install taskwarrior on WSL Ubuntu, however, I think this is a Java problem since I can see that the reader does contain all lines/information, hence for completeness: the complete method that runs the command is:</p>
  
  <pre><code>package customSortServer;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.PrintWriter;
  import java.util.ArrayList;
  import java.util.Map;
  import java.util.StringJoiner;
  
  public class RunCommandsLongOutput2 {
      /**
       * This executes the commands in terminal. Additionally it sets an environment
       * variable (not necessary for your particular solution) Additionally it sets a
       * working path (not necessary for your particular solution)
       * 
       * @param commandData
       * @param ansYes
       * @throws Exception
       */
      public static ArrayList&lt;String&gt; executeCommands(Command command, Boolean ansYes) {
          ArrayList&lt;String&gt; capturedCommandOutput = new ArrayList&lt;String&gt;();
          File workingDirectory = new File(command.getWorkingDirectory());
  
          // create a ProcessBuilder to execute the commands in
          ProcessBuilder processBuilder = new ProcessBuilder(command.getCommandLines());
  
          // this is set an environment variable for the command (if needed)
          if (command.isSetEnvVar()) {
              processBuilder = setEnvironmentVariable(processBuilder, command);
          }
  
          // this can be used to set the working directory for the command
          if (command.isSetWorkingPath()) {
              processBuilder.directory(workingDirectory);
          }
  
          // execute the actual commands
          try {
              Process process = processBuilder.start();
              System.out.println("Started");
              if (command.isGetOutput()) {
  
                  // capture the output stream of the command
                  BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
  //              System.out.println(reader.lines().count());
  //              long counter = 0;
                  while (reader.lines().iterator().hasNext()) {
  
                      capturedCommandOutput.add(reader.lines().iterator().next());
                  }
  //              while (reader.lines().iterator().hasNext()) {
  //                  counter++;
  //                  System.out.println("line=" + reader.lines().iterator().next());
  //              }
              }
  
              // connect the output of your command to any new input.
              // e.g. if you get prompted for `yes`
              new Thread(new SyncPipe(process.getErrorStream(), System.err)).start();
              new Thread(new SyncPipe(process.getInputStream(), System.out)).start();
              PrintWriter stdin = new PrintWriter(process.getOutputStream());
  
              // This is not necessary but can be used to answer yes to being prompted
              if (ansYes) {
                  stdin.println("yes");
              }
  
              // write any other commands you want here
              stdin.close();
  
              // If the command execution led to an error, returnCode!=0, or not (=0).
              int returnCode = process.waitFor();
              System.out.println("Return code = " + returnCode);
          } catch (IOException e1) {
              e1.printStackTrace();
          } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
          // return output if required:
          return capturedCommandOutput;
      }
  
      /**
       * source: https://stackoverflow.com/questions/7369664/using-export-in-java
       * 
       * @param processBuilder
       * @param varName
       * @param varContent
       * @return
       */
      private static ProcessBuilder setEnvironmentVariable(ProcessBuilder processBuilder, Command command) {
          Map&lt;String, String&gt; env = processBuilder.environment();
          env.put(command.getEnvVarName(), command.getEnvVarContent());
          processBuilder.environment().put(command.getEnvVarName(), command.getEnvVarContent());
          return processBuilder;
      }
  }
  </code></pre>
  
  <p>And the method that generates the command is:</p>
  
  <pre><code>    public static void createCommandToGetUrgencyList(HardCoded hardCoded) {
  
          // create copy command
          Command command = new Command();
          String[] commandLines = new String[2];
          commandLines[0] = "task";
          commandLines[1] = hardCoded.getGetUrgencyReportName();
          command.setCommandLines(commandLines);
          command.setEnvVarContent("/var/taskd");
          command.setEnvVarName("TASKDDATA");
          command.setWorkingPath("/usr/share/taskd/pki");
          command.setGetOutput(true);
  
          // execute command to copy file
          ArrayList&lt;String&gt; urgencyList = RunCommandsLongOutput2.executeCommands(command, false);
          System.out.println("The urgency list has length = "+urgencyList.size());
          for (int i = 0; i &lt; urgencyList.size(); i++) {
              System.out.println("The output of the command =" + urgencyList.get(i));
          }
      }
  </code></pre>