I have a method which return list of items and takes a limit (used by Stream#limit
) as parameter:
public List<Integer> getItems(Long limit) {
return IntStream.range(1, 10)
.limit(limit)
.boxed()
.collect(Collectors.toList());
}
How to set the parameter to take all items (with no limit)?
My attempts:
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
Passing Long.MAX_VALUE
is not a solution.
MongoDB inconsistency
For example MongoDB's FindIterable#limit
can take 0
or null
as no limit.
public List<Integer> getItems(Long limit) {
MongoDatabase mongo = new MongoClient().getDatabase("example");
MongoCollection<Document> documents = mongo.getCollection("items");
FindIterable<Document> founded = documents.find();
List<Integer> items = new ArrayList<>();
for (Document doc : founded.limit(limit.intValue())) {
items.add(doc.getInteger("number"));
}
return items;
}
This inconsistency between methods causes incompatibility, for example one interface with method List<Integer> getItems(Long limit)
and two implementations: in memory and MongoDB.
Consistency in methods Stream#skip
and FindIterable#skip
is preserved.
--------------------------
| Java | Mongo |
------------------------------------
limit = 0 | none items | all items |
------------------------------------
skip = 0 | none skip | none skip |
------------------------------------
Refactor method with Stream#limit
I guess there is no way to pass "no limit" parameter to Stream#limit
, so I must refactor this method to takes "limit" and 0
or null
or -1
as "no limit".
public static List<Integer> 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());
}
}
Or:
public static List<Integer> getItems(Long limit) {
IntStream items = IntStream.range(1, 10);
if (limit != null && limit != 0 && limit != -1) {
items = items.limit(limit);
}
return items.boxed()
.collect(Collectors.toList());
}
There is a better way to achieve consistency between methods limit
?