title: IntStream.range(0, 1_000_000) stops at 113383 (Project Euler: Longest Collatz Sequence)
body: <p>I have a strange problem in my code to answer this:</p>
  
  <blockquote>
    <p>The following iterative sequence is defined for the set of positive integers:</p>
    
    <p>n → n/2 (n is even)<br>
    n → 3n + 1 (n is odd)</p>
    
    <p>Using the rule above and starting with 13, we generate the following sequence:<br>
    13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1</p>
    
    <p>It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms.   Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.</p>
    
    <p>Which starting number, under one million, produces the longest chain?</p>
    
    <p>NOTE: Once the chain starts the terms are allowed to go above one million.</p>
  </blockquote>
  
  <pre><code>public class Problem14 extends Problem&lt;Integer&gt; {
      private final int maximum;
  
      public Problem14(final int maximum) {
          this.maximum = maximum;
      }
  
      @Override
      public void run() {
          result = IntStream.range(1, maximum).boxed()
                  .peek(System.out::println)
                  .collect(Collectors.toMap(i -&gt; i, i -&gt; (int)Iterators.intStream(new CollatzGenerator(i)).count()))
                  .entrySet().stream()
                  .peek(System.out::println)
                  .max(Comparator.comparingInt(Map.Entry::getValue))
                  .get().getKey();
      }
  
      @Override
      public String getName() {
          return "Problem 14";
      }
  }
  </code></pre>
  
  <hr>
  
  <pre><code>public abstract class Problem&lt;T&gt; implements Runnable {
      protected T result;
  
      public String getResult() {
          return String.valueOf(result);
      }
  
      abstract public String getName();
  }
  </code></pre>
  
  <hr>
  
  <pre><code>public class CollatzGenerator implements PrimitiveIterator.OfInt {
      private int current;
  
      public CollatzGenerator(final int start) {
          if (start &lt; 1) {
              throw new IllegalArgumentException("generators.CollatzGenerator: start &lt; 1: start = " + start);
          }
          this.current = start;
      }
  
      @Override
      public boolean hasNext() {
          return (current != 1);
      }
  
      @Override
      public int nextInt() {
          int returnInt = current;
          if (current % 2 == 0) {
              current /= 2;
          }
          else {
              current = 3 * current + 1;
          }
          return returnInt;
      }
  }
  </code></pre>
  
  <hr>
  
  <pre><code>public abstract class Iterators {
      //...
  
      public static IntStream intStream(final PrimitiveIterator.OfInt iterator) {
          return StreamSupport.intStream(
                  Spliterators.spliteratorUnknownSize(iterator, 0), false
          );
      }
  
      //...
  }
  </code></pre>
  
  <p>Calling code is along the lines of:</p>
  
  <pre><code>new Problem14(1_000_000).run();
  </code></pre>
  
  <p>So to rephrase, the problem is that the program never terminates, what I do see is that it prints all integers from 1 to 113383, presumably from the first <code>.peek(System.out::println)</code> call.</p>
  
  <p>Also an extra question is that, currently I box my <code>IntStream</code> to a <code>Stream&lt;Integer&gt;</code> to be able to do <code>.collect(Collectors.toMap(i -&gt; i, i -&gt; (int)Iterators.intStream(new CollatzGenerator(i)).count()))</code>...<br>
  I'd like to get rid of the boxing and use the <code>IntStream::collect</code> method, however I do not understand how to do it.</p>