Java 如果列表的总大小小于限制,stream().limit()会优化执行吗?
如果Java 如果列表的总大小小于限制,stream().limit()会优化执行吗?,java,java-8,java-stream,limit,Java,Java 8,Java Stream,Limit,如果限制值大于列表的大小,java会优化而不执行此代码吗 List<Long> someList = Arrays.asList(1L, 2L, 3L, 4L, 5L); int limit = 5; List<Long> limitedList = someList.stream().limit(limit).collect(Collectors.toList()); List-someList=Arrays.asList(1L、2L、3L、4L、5L); 整数极限=
限制
值大于列表的大小
,java会优化而不执行此代码吗
List<Long> someList = Arrays.asList(1L, 2L, 3L, 4L, 5L);
int limit = 5;
List<Long> limitedList = someList.stream().limit(limit).collect(Collectors.toList());
List-someList=Arrays.asList(1L、2L、3L、4L、5L);
整数极限=5;
List limitedList=someList.stream().limit(limit).collect(collector.toList());
比如说,limit=1000000
和someList.size()=99999
现在,java是否足够智能,能够理解列表大小小于限制?
或者它会盲目地检查列表中的每个数字,直到它到达列表的末尾或达到限制吗?stream()。限制(5)
不是终端操作,因此您不能像我那样限制列表,它会将限制值存储在limitedlist
。即使使用collect()
也无法限制列表并将其存储在limitedlist
中,因为类型不匹配将发生
您需要使用.collect()
作为终端操作,然后使用收集器。toList()
将其添加到limitedlist
,不要尝试在同一行中打印它,因为它会抛出错误,说类型不匹配
流操作是延迟执行的,因此Java不会抛出错误,因为它不知道列表的限制,因此如果限制大小超过列表的实际大小,那么它将返回所有元素的最大值
List<Long> someList = Arrays.asList(1L, 2L, 3L, 4L, 5L);
List<Long> limitedList = someList.stream().limit(5).collect(Collectors.toList());
for(long aa:limitedList)
{
System.out.println(aa);
}
输出:结果将是整个somelist
元素
List<Long> someList = Arrays.asList(1L, 2L, 3L, 4L, 5L);
List<Long> limitedList = someList.stream().limit(5).collect(Collectors.toList());
for(long aa:limitedList)
{
System.out.println(aa);
}
PS:流不是一个数据结构,流操作是惰性执行的。让我们试试看。以下是您的代码版本,其中列表的总大小小于限制(如标题所示): []
此处
toList
从skip
请求元素<代码>跳过首先尝试从列表中获取6个元素。4点之后,列表将用尽。此时,skip
告诉toList
没有更多的元素,因此toList
返回一个空列表。同样,没有任何东西需要优化。不,它不会优化执行(即使在JDK 11中)
让我们尝试最简单的终端操作(count
):
该程序将打印:
1
2
3
4
5
5
因此,它必须遍历整个流才能找到确切的大小。
stream#limit
不是一个终端操作,因此无论如何都不会执行任何操作。您的代码也不会编译,因为Stream#limit
不会返回列表
@ErwinBolwidt不,我假设OP打算执行.collect(toList())
。由于流操作是延迟执行的,Java将无法识别大小,因此,输出会将大小限制为max
。它可能已优化或将来会优化--列表可以返回一个知道大小并优化limit()的流,可能使用大小拆分器--但可能不是这样。这可能对您来说并不重要,但是如果对您来说重要,那么您应该自己检查大小,而不是依赖当前实现的隐藏细节。我怀疑Java是否能够优化它(或者实际上能够),因为中间操作不需要知道当前提供输入的是哪种底层结构。这是我的意图。不知何故没有添加.collect(Collectors.toList())在这里输入时。请试着理解问题和itI背后的意图。我已经试着理解情况,Java似乎无法优化它,如果限制恰好大于实际列表大小,它将返回最大大小。因此,它将返回实际列表的完整大小,这就是我所说的。@ZhekaKozlov这样的优化是完全可能的,但很可能是无用的,因为在这种情况下,您所关心的只是限制现有的集合,而无需其他中间操作,因此这很容易通过size
和subList
实现。@Eugene我不认为这是无用的。毕竟,选项count()的最大化在大小的
流上被认为是值得在Java 9中添加的。那么为什么不将同样的考虑应用到有限制的流上呢?只是当前的实现无法保持大小的
特性。在我自己的实现中,它是。这对于像toArray@Eugene@Holger是对的。list.stream().limit().toArray()
如果知道确切的大小,效率会更高。您可能应该澄清您正在解决的优化类型,因为这个问题不是很清楚。我的解释是limit()
对于给定大小的流,可能是不可操作的,但这并不能证明这一点。
List<Long> limitedList = someList.stream().skip(6).collect(Collectors.toList());
var someList = Arrays.asList(1, 2, 3, 4, 5);
var limit = 10_000;
System.out.println(someList
.stream()
.peek(System.out::println)
.limit(limit)
.count());
1
2
3
4
5
5