【发布时间】:2019-03-24 20:16:24
【问题描述】:
我有一个方法,它返回项目列表并将限制(由Stream#limit 使用)作为参数:
public List<Integer> getItems(Long limit) {
return IntStream.range(1, 10)
.limit(limit)
.boxed()
.collect(Collectors.toList());
}
如何设置参数取所有项目(无限制)?
我的尝试:
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
传递Long.MAX_VALUE 不是解决方案。
MongoDB 不一致
例如MongoDB的FindIterable#limit可以以0或null为无限制。
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;
}
方法之间的这种不一致会导致不兼容,例如一个接口与方法 List<Integer> getItems(Long limit) 和两个实现:在内存中和 MongoDB。
保留方法 Stream#skip 和 FindIterable#skip 的一致性。
--------------------------
| Java | Mongo |
------------------------------------
limit = 0 | none items | all items |
------------------------------------
skip = 0 | none skip | none skip |
------------------------------------
使用 Stream#limit 重构方法
我想没有办法将“无限制”参数传递给Stream#limit,所以我必须重构这个方法以将“限制”和0或null或-1作为“无限制”。
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());
}
}
或者:
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());
}
有没有更好的方法来实现方法limit之间的一致性?
【问题讨论】:
-
你所拥有的对我来说看起来不错
-
为什么“传递
Long.MAX_VALUE不是解决方案”? -
传递
Long.MAX_VALUE不是解决方案,因为它只是一种解决方法。在这种情况下(在从数据库中获取的内存实现替换中)理论上风险可能超过2^63-1记录;)(但实际上它不是一个论点)。但我想知道如何使用 Java 流。内存中的 Java 流可能很长甚至无穷大(例如IntStream.iterate(0, i -> i + 1)),并且可能存在Long.MAX_VALUE太小的情况。 -
使用最新版本。不想要限制的时候不要打电话
limit,但要避免代码重复。当然,当流源已经支持某个大小时(如IntStream.range、Arrays.stream(…)、List.subList(…).stream()或Random.ints(…)),您应该首先指定大小。使用limit,即使使用Long.MAX_VALUE有性能缺陷。
标签: java mongodb java-stream