当数字等于0时,如何跳过流的限制(数字)调用?

2022-09-02 09:20:37

我有一些Java代码,它提供了来自.它根据以下条件限制它们:itemsmaxNumber

items.stream()
     .map(this::myMapper)
     .filter(item -> item != null)
     .limit(maxNumber)
     .collect(Collectors.toList());

它工作正常,但问题是:有没有办法跳过限制,当?maxNumber == 0

我知道我可以这样做:

if (maxNumber == 0) {
    items.stream()
         .map(this::myMapper)
         .filter(item -> item != null)
         .collect(Collectors.toList());
} else {
    items.stream()
         .map(this::myMapper)
         .filter(item -> item != null)
         .limit(maxNumber)
         .collect(Collectors.toList());
}

但也许有更好的方法,你有没有想到什么?


答案 1

不,流管道不允许实际跳过管道的任何部分,因此您被迫在步骤中使用条件逻辑并包括管道中的始终,或者将流构建在比问题中的if/else更清晰(恕我直言)的部分limit()

Stream<Item> s = items.stream()
         .map(this::myMapper)
         .filter(Objects::nonNull);

if(maxNumber > 0) {
    s = s.limit(maxNumber);
}

List<Item> l = s.collect(Collectors.toList());

在像这里这样的简单案例中,它没有太大区别,但是您经常看到常规代码集合通过方法传递,转换为流,然后返回到集合。在这种情况下,最好分批使用流,直到您真正需要 。collect()


答案 2

我想

.limit(maxNumber == 0 ? Long.MAX_VALUE : maxNumber)

将做到这一点,因为您极不可能处理具有超过2 ^ 63-1元素的流...

至少要小心并行流...API文档中的注释说:

API 注意:虽然在顺序流管道上通常是一种廉价的操作,但在有序并行管道上它可能非常昂贵,特别是对于 maxSize 的大值...limit()


推荐