【问题标题】:Java 8 streams adding values from two or more listsJava 8 流从两个或多个列表中添加值
【发布时间】:2015-04-19 23:31:46
【问题描述】:

我正在尝试进入 Java 8 并围绕流和 lambda 来解决各种问题,并陷入了这个特定的问题,我通常使用 forEach 并将值存储在 Map 中来解决。

您将如何编写代码以使用 Java 8 中的新功能获得预期列表?

List<Integer> voterA = Arrays.asList(1,2,3,4,5);
List<Integer> voterB = Arrays.asList(1,2,3,4,5);
List<List<Integer>> votes = Arrays.asList(voterA, voterB);

// expected list = (2,4,6,8,10)
List<Integer> sumVotes = ...

【问题讨论】:

  • 您将如何使用增强型循环来解决它?
  • 看看question

标签: java java-8


【解决方案1】:

这并不像您希望的那样真正可行。你能得到的最接近的可能是

IntStream.range(0, voterA.size())
    .mapToObj(i -> voterA.get(i) + voterB.get(i))
    .collect(toList());

...但是对流没有“zip”操作,主要是因为两个不同的流可以具有在不同点拆分的支持拆分器,因此您无法正确排列它们。

【讨论】:

  • 令人讨厌的是,我可以确切地看到我在 LINQ 中的 C# 中是如何做到这一点的——以一种非常普遍的方式——但当涉及到 Java 流时,我仍在摸索。也许当我得到更多的练习......
  • 我的意思是...我查看 Spliterator 界面,我不认为有任何 nice 方法可以进行压缩,只是因为 trySplit 允许拆分发生在任意点。您可以使用 SUBSIZED 拆分器有效地进行索引,并回退到其他拆分器的效率较低的顺序方法,但我认为您无法使用压缩来做任何事情。
  • 这是 C# 版本,包含 3 个具有不同列表长度的选民:gist.github.com/jskeet/2c1db126e424cf58cb69
  • 我的意思是,这可以直接转化为gist.github.com/lowasser/e1b57e1a9358cbf52cc6
  • @LouisWasserman 让拆分器排列它们的拆分,尤其是并行拆分,这无疑是一个大问题。另一个问题是您真的希望压缩两个(或 N 个)流的结果是另一个流。它的元素类型是什么? PairTuple 类?或者提供一个成对组合元素的BiFunction?但是我们没有 N 元函数。我们仍在努力解决这个问题,但在我们拥有值类型(> Java 9)之前,它看起来不会出现任何东西。
【解决方案2】:

JDK 不提供“zip”API。但是可以通过第三个库AbacusUtil来完成:

List<Integer> voterA = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> voterB = Arrays.asList(1, 2, 3, 4, 5);

List<Integer> sumVotes = Stream.zip(voterA, voterB, (a, b) -> a + b).toList();

披露:我是AbacusUtil的开发者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 2017-06-01
    相关资源
    最近更新 更多