我需要在列表的页面上进行处理。 因此,我想知道在以下两者之间(在性能和良好实践方面)哪个更好:
public List<Other> function(List<Something> somethingList,
int offset, int pageSize) {
return somethingList.stream().skip(offset * pageSize).limit(pageSize)
.map(s -> doSomething(s)).collect(Collectors.toList());
}
或:
public List<Other> function(List<Something> somethingList,
int offset, int pageSize) {
return somethingList.subList(offset * pageSize, offset * pageSize + pageSize)
.stream().map(s -> doSomething).collect(Collectors.toList());
}
我省略了对偏移量和页面大小的自愿验证。
编辑:性能并不是至关重要的需求,我的问题还在于清晰度,维护和良好实践。我更喜欢流的方式,尤其是因为它需要较少的验证。但我更希望确保这不是性能的真正损失或维护性/清洁性较差的东西。
答案 0 :(得分:2)
区别在于流操作的排序方式。 Java Stream API。跳过的国家很便宜。
尽管skip()在顺序流管道上通常是便宜的操作,但在有序并行管道上却可能非常昂贵,尤其是对于较大的n值,因为skip(n)不仅被限制为不仅可以跳过n个元素,而且还可以跳过遇到顺序中的前n个元素。如果情况的语义允许,则使用无序流源(例如generate(Supplier))或使用BaseStream.unordered()删除排序约束可能会导致并行管道中skip()的显着加速。如果需要与遇到顺序保持一致,并且在并行管道中使用skip()遇到性能低下或内存使用率不足的情况,则切换为使用BaseStream.sequential()顺序执行可能会提高性能。
和
Limit:返回一个由该流的元素组成的流,并在从结果流中消耗掉元素后,另外对每个元素执行提供的操作。
在子列表上使用流的一个好处是,您可以应用过滤器和/或您询问的逻辑,与创建子列表相比,它可能会更便宜。尽管流按功能顺序发生,但某些元素可能会被过滤掉,而您只需要执行一次流。在列出项目时,您可能不得不循环多次并使用多个对象临时保留这些项目;通常会遍历该项目相同的不需要功能。
您的问题非常具体。这些相同的原则将适用于列表中的实际情况。 Power of streams。在引擎盖下,流中可能仍然有多个对象。但是当对一组元素执行复杂的操作时,复杂性就从程序员那里移走了。简而言之,它可以替代许多背靠背的循环,而在循环中我们使用顶级过程元素。它们确实是实用程序。 Streams can replace for loops。