用java 8 foreach替换for循环以更新值

Gon*_*n I 2 java foreach lambda java-8 java-stream

我想用优雅的java 8流或lambda解决方案替换以下for循环.有什么简洁有效的吗?

    public static void main(String[] args) {
        ArrayList<Integer> myList = new ArrayList<>( Arrays.asList( 10,-3,5));

        // add 1/2 of previous element to each element
        for(int i =1 ;i < myList.size();  ++i )
            myList.set(i, myList.get(i)+myList.get(i-1)/2);

        // myList.skip(1).forEach( e -> e + prevE/2 );  // looking for something in this spirit
    }
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 8

您的循环评估依赖于先前评估的结果.它相当于

for(int i = 1, value = myList.get(0); i < myList.size(); i++ ) {
    value = myList.get(i) + value/2;
    myList.set(i, value);
}
Run Code Online (Sandbox Code Playgroud)

通过使用Stream API或lambda表达式,没有真正的简化.实际上,我更喜欢上面显示的变体,即使它更大而不是更小,因为它清楚地表明了实际发生的事情(并且通过避免多次List查找可能会稍微提高效率).

如果您创建一个新的,它还允许您独立编程位置List:

List<Integer> srcList = Arrays.asList(10, -3, 5), dstList = new ArrayList<>();

int value = 0;
for(Integer i: srcList) {
    value = i + value/2;
    dstList.add(value);
}
Run Code Online (Sandbox Code Playgroud)

  • @ holi-java这就是我所说的"没有真正的简化".您可以这样做,但由于该函数不是关联的,因此无法提供有效的拆分支持,因此您最终会得到更复杂的代码而无法获得真正的好处. (3认同)

Ant*_*iuc 6

无法访问java流中的前一个元素.您可能会使用,IntStream#range但它看起来不优雅:

IntStream.range(1, myList.size())
        .forEachOrdered(i -> myList.set(i, myList.get(i) + myList.get(i - 1) / 2));
Run Code Online (Sandbox Code Playgroud)

  • 同意,有时候你需要一个for循环. (3认同)