java 使用 lambdas 的 List<> 的 Java8 子列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43192354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 07:09:50  来源:igfitidea点击:

Java8 sublists of a List<> using lambdas

javalistlambdajava-8java-stream

提问by Peter Andersson

I have a problem which I feel would be perfect for streams and/or lambdas. On the other hand I don't want to overcomplicate this, but since will use this specific technique in many variations (run function on a sublist), I would like some ideas about how to get it right from the beginning.

我有一个问题,我觉得它非常适合流和/或 lambda。另一方面,我不想将其复杂化,但由于将在许多变体中使用此特定技术(在子列表上运行函数),因此我想要一些有关如何从一开始就正确使用它的想法。

I have a List<Product> productList.

我有一个List<Product> productList.

I want to be able to iterate over all sublists in productList. For example all sublists with size=30. This sublist should then be used as an argument to a function.

我希望能够遍历productList. 例如所有大小为 30 的子列表。然后应将此子列表用作函数的参数。

This is my current, naive, solution:

这是我目前的天真解决方案:

List<Product> products=...
// This example uses sublists of size 30
for (int i = 0; i < products.size() - 29; i++) {
    // sublist start index is inclusive, but end index is exclusive
    List<Product> sublist = products.subList(i, i + 30);
    Double res = calc(sublist);
}

// an example of a function would be moving average

How would this be implemented using lambdas?

这将如何使用 lambda 实现?

EDIT I tried to come up with the simplest possible example to illustrate the problem. After some comments, I realized that a perfect example is calculating a moving average. First MAVG is calculated on sublist [0..29], second on [1..30], third on [2..31] and so on.

编辑我试图想出一个最简单的例子来说明这个问题。经过一些评论后,我意识到一个完美的例子是计算移动平均线。第一个 MAVG 在子列表 [0..29] 上计算,第二个在 [1..30] 上,第三个在 [2..31] 上,依此类推。

回答by Eugene

Unless I'm missing something obvious...

除非我遗漏了一些明显的东西......

IntStream.range(0, products.size() - 29)
            .mapToObj(i -> products.subList(i, i + 30))
            .map(list -> calc(list))
            .forEach... // or any other terminal op

Well if you want to run more then a single function to these sublists, like:

好吧,如果您想对这些子列表运行多个函数,例如:

double result = calc(sublist)
log(sublist) // void
double res = diffCalc(sublist)

you are probably off staying with the usual for loop.

您可能不会继续使用通常的 for 循环。

a mapoperation does a single action on a sublist, it could be made to do more in a stream, but that will look really ugly IMO.

一个map操作确实在子列表一个动作,它可以进行做多流,但看起来真难看IMO。

回答by ZhekaKozlov

If you don't mind using third party libraries, there is a method subListsin StreamExthat does exactly what you want:

如果你不介意使用第三方库,有一个方法subListsStreamEx那不正是你想要什么:

List<Product> products = ...
Stream<List<Product>> lists = StreamEx.ofSubLists(products, 30, 1);

回答by oleg.cherednik

I think that code could be less clear with using lambdas. Maybe plain old ifis better that modern lambda?

我认为使用 lambdas 代码可能不太清楚。如果比现代lambda更好,也许是旧的?

    int sizeSubList = 30;

    for (int i = 0; i < products.size(); i++)
        calc(products.subList(i, Math.min(i + sizeSubList, products.size())));