我有一个问题,我认为这对溪流和/或lambdas来说是完美的。另一方面,我不想过于复杂,但由于将在许多变体中使用这种特定的技术(在子列表上运行函数),我想要一些关于如何从一开始就做到这一点的想法。
我有List<Product> productList
。
我希望能够遍历productList
中的所有子列表。例如,大小= 30的所有子列表。然后,该子列表应该用作函数的参数。
这是我现在的,天真的解决方案:
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
如何使用lambdas实现?
EDIT 我试图用最简单的例子来说明问题。经过一些评论,我意识到一个完美的例子是计算移动平均线。第一个MAVG在子列表[0..29]上计算,第二个在[1..30]上计算,第三个在[2..31]上计算,依此类推。
答案 0 :(得分:6)
除非我遗漏了一些明显的东西......
IntStream.range(0, products.size() - 29)
.mapToObj(i -> products.subList(i, i + 30))
.map(list -> calc(list))
.forEach... // or any other terminal op
如果您想为这些子列表运行更多单个函数,例如:
double result = calc(sublist)
log(sublist) // void
double res = diffCalc(sublist)
你可能不习惯常规的循环。
map
操作在子列表上执行单个操作,可以在流中执行更多操作,但这看起来非常难看IMO。
答案 1 :(得分:4)
如果您不介意使用第三方库,StreamEx中的方法subLists
可以完全符合您的要求:
List<Product> products = ...
Stream<List<Product>> lists = StreamEx.ofSubLists(products, 30, 1);
答案 2 :(得分:1)
我认为使用lambdas时代码可能不太清楚。也许普通的如果比现代 lambda 更好?
int sizeSubList = 30;
for (int i = 0; i < products.size(); i++)
calc(products.subList(i, Math.min(i + sizeSubList, products.size())));