在Java 8中减少集合的内容。

huangapple go评论69阅读模式
英文:

Reducing a Collection in Java 8

问题

我想知道什么是最清晰、也许是最惯用的方式来处理类似于以下简单示例的情况。

如果我有一个数组(或列表等)[1,1,1,2,3,5,5,9],我想要进行一种归约操作,类似于折叠,其中连续的数字会相加,只留下一个元素。

因此[1,1,1,2,3,5,5,9]会变成[3,2,3,10,9]


稍微更一般化的情况:

[object1, object2, object3, object4],其中object1object2具有某些属性的组合,这将使得需要创建一个新的object5来替换它们两个,结果将变为[object5, object3, object4]

我的实际用例要复杂一些,但基本思想是类似的,在某种程度上迭代处理列表,但不是归约为单个原子值。

英文:

I am wondering what is the cleanest , perhaps idiomatic, way to something like the following trivial example.

If I have an array (or list, etc) [1,1,1,2,3,5,5,9] I want to do a reduction, fold, of sorts, where consecutive numbers are added, leaving only one element.

So [1,1,1,2,3,5,5,9] would become [3,2,3,10,9].


A slightly more generalized case:

[object1, object2, object3, object4] where object1 and object2 have some combination of properties that would make it necessary to create a new object5 to replace both of them and the result would be [object5, object3, object4].

My actual use case is a bit more complicated, but the idea is similar in iterating over a list, somehow, but not reducing to a single atomic value.

答案1

得分: 0

减少Stream API的工作方式不是这样的。 减少(也称为fold)的重点是将输入元素合并为单个结果。

只要计算依赖于基于等价性的连续元素,这显然不适合Stream API。

你想要做类似这样的事情*...但是我不知道如何将其“转换”为Stream API。

List<Integer> list = Arrays.asList(1, 1, 1, 2, 3, 5, 5, 9);
List<Integer> newList = new ArrayList<>();

int i = 0;
while (i < list.size()) {
    int current = list.get(i);
    int next = current;
    int sum = 0;
    int j = i;
    while (current == next) {
        j++;
        sum += next;
        if (j < list.size()) {
            next = list.get(j);
        } else break;
    }
    newList.add(sum);
    i = j;
}

// [3, 2, 3, 10, 9]
System.out.println(newList);

*从性能和可读性的角度来看,这显然不是最佳解决方案,只要我在解决“LeetCode”问题方面真的很差。思路是展示这些解决方案与Stream API不兼容。

英文:

The reduction is Stream API doesn't work this way. The point of the reduction (also called as fold) is to combine input elements into a single result.

This is clearly not a suitable task for Stream API as long as the computation relies on the consecutive elements based on the equivalence.

You want go for something like this*... which I have no idea to "convert" into Stream API.

List&lt;Integer&gt; list = Arrays.asList(1,1,1,2,3,5,5,9);
List&lt;Integer&gt; newList = new ArrayList&lt;&gt;();

int i = 0;
while (i &lt; list.size()) {
    int current = list.get(i);
    int next = current;
    int sum = 0;
    int j = i;
    while (current == next) {
        j++;
        sum += next;
        if (j &lt; list.size()) {
            next = list.get(j);
        } else break;
    }
    newList.add(sum);
    i = j;
}

// [3, 2, 3, 10, 9]
System.out.println(newList);                  

*This is clearly not the best solution in terms of performance and readability as long as I really suck in "LeetCode" problems solving. The idea is to demonstrate these solutions don't go well with Stream API.

huangapple
  • 本文由 发表于 2020年7月24日 20:12:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/63073324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定