title: Java stream parameter limit with no limit (MongoDB inconsistency)
body: <p>I have a method which return list of items and takes a limit (used by <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#limit-long-" rel="nofollow noreferrer"><code>Stream#limit</code></a>) as parameter:</p>
  
  <pre><code>public List&lt;Integer&gt; getItems(Long limit) {
      return IntStream.range(1, 10)
              .limit(limit)
              .boxed()
              .collect(Collectors.toList());
  }  
  </code></pre>
  
  <p>How to set the parameter to take all items (with no limit)?</p>
  
  <p>My attempts:</p>
  
  <pre><code>    Long limit5 = 5L;
      System.out.println("With limit 5:" + getItems(limit5));
      // works fine: 5 items
  
      Long noLimitZero = 0L;
      System.out.println("Without limit (zero): " + getItems(noLimitZero));
      // why 0 mean "no items" instead of "all items"
  
     Long noLimitNegative = -1L;
      System.out.println("Without limit (negative number): " + getItems(noLimitNegative));
      // IllegalArgumentException
  
      Long noLimitNull = null;
      System.out.println("Without limit (null): " + getItems(noLimitNull));
      // NullPointerException
  </code></pre>
  
  <p>Passing <code>Long.MAX_VALUE</code> is not a solution.</p>
  
  <h3>MongoDB inconsistency</h3>
  
  <p>For example MongoDB's <a href="http://mongodb.github.io/mongo-java-driver/3.6/javadoc/com/mongodb/client/FindIterable.html#limit-int-" rel="nofollow noreferrer"><code>FindIterable#limit</code></a> can take <code>0</code> or <code>null</code> as no limit.</p>
  
  <pre><code>public List&lt;Integer&gt; getItems(Long limit) {
      MongoDatabase mongo = new MongoClient().getDatabase("example");
      MongoCollection&lt;Document&gt; documents = mongo.getCollection("items");
      FindIterable&lt;Document&gt; founded = documents.find();
      List&lt;Integer&gt; items = new ArrayList&lt;&gt;();
      for (Document doc : founded.limit(limit.intValue())) {
          items.add(doc.getInteger("number"));
      }
      return items;
  }
  </code></pre>
  
  <p>This inconsistency between methods causes incompatibility, for example one interface with method <code>List&lt;Integer&gt; getItems(Long limit)</code> and two implementations: in memory and MongoDB.</p>
  
  <p>Consistency in methods <code>Stream#skip</code> and <code>FindIterable#skip</code> is preserved.</p>
  
  <pre><code>          --------------------------
            | Java       | Mongo     |
  ------------------------------------
  limit = 0 | none items | all items |
  ------------------------------------
  skip = 0  | none skip  | none skip |
  ------------------------------------
  </code></pre>
  
  <h3>Refactor method with Stream#limit</h3>
  
  <p>I guess there is no way to pass "no limit" parameter to <code>Stream#limit</code>, so I must refactor this method to takes "limit" and <code>0</code> or <code>null</code> or <code>-1</code> as "no limit".</p>
  
  <pre><code>public static List&lt;Integer&gt; getItems(Long limit) {
      if (limit == null || limit == 0 || limit == -1) {
          return IntStream.range(1, 10)
                  .boxed()
                  .collect(Collectors.toList());
      } else {
          return IntStream.range(1, 10)
                  .limit(limit)
                  .boxed()
                  .collect(Collectors.toList());
      }
  }
  </code></pre>
  
  <p>Or:</p>
  
  <pre><code>public static List&lt;Integer&gt; getItems(Long limit) {
      IntStream items = IntStream.range(1, 10);
      if (limit != null &amp;&amp; limit != 0 &amp;&amp; limit != -1) {
          items = items.limit(limit);
      }
      return items.boxed()
              .collect(Collectors.toList());
  }
  </code></pre>
  
  <p>There is a better way to achieve consistency between methods <code>limit</code>?</p>