【问题标题】:Java8 sublists of a List<> using lambdas使用 lambda 的 List<> 的 Java8 子列表
【发布时间】:2017-08-28 18:36:53
【问题描述】:

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

我有一个List&lt;Product&gt; productList

我希望能够遍历productList 中的所有子列表。例如所有 size=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 实现?

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

【问题讨论】:

  • 相反,使用流和 lambda 不会使代码更具可读性。
  • 您要解决的更大问题是什么,为什么需要 30 个子列表?此外,您制作的不是 30 大小的子列表,而是一个比完整列表小的 29 个产品的列表。
  • 这只是一个例子,上面的代码可以工作(至少原来使用相同类型的解决方案 - 这是一个简化的例子)。有关更多上下文,请参阅编辑。
  • @ZhekaKozlov 不是真的,使用那个例子,我想要子列表:['a','b','c'],['b','c'.'d'],[ 'c','d','e'],['d','e','f'] 等等,就像一个“滑动窗口”

标签: java list lambda java-8 java-stream


【解决方案1】:

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

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)

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

map 操作对子列表执行单个操作,它可以在流中执行更多操作,但 IMO 看起来真的很难看。

【讨论】:

  • 我想这就是我要找的东西,但我不能说我明白。在我的编辑中计算移动平均线时,您会考虑这种“最先进的技术”吗?
  • BTW... 任意常量(29 和 30)正是我在示例使用大小为 30 的子列表时使用的。
  • @PeterAndersson 这是iterating over indexes 相当标准的代码。
  • ^ 如果您仅逐一扫描列表,则可以显着更有效地计算移动平均线。
  • @9000 移动平均线详情添加在答案后。
【解决方案2】:

如果您不介意使用第三方库,StreamEx 中有一个方法 subLists 可以满足您的需求:

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

【讨论】:

    【解决方案3】:

    我认为使用 lambda 时代码可能不太清晰。也许普通的旧 if 比现代的 lambda 更好?

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

    【讨论】:

    • 是的,我可能会坚持使用旧方法。但是,您的代码的一个问题是某些列表将小于 30 个项目,我的示例中的硬编码偏移量会处理这些问题。不过还是谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多