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

时间:2018-02-01 11:02:33

标签: java lambda foreach 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
    }

3 个答案:

答案 0 :(得分:8)

您的循环评估与先前评估的结果有关。它相当于

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

通过使用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);
}

答案 1 :(得分:5)

无法访问java流中的上一个元素。 您可以使用IntStream#range,但它看起来并不优雅:

IntStream.range(1, myList.size())
        .forEachOrdered(i -> myList.set(i, myList.get(i) + myList.get(i - 1) / 2));

答案 2 :(得分:2)

是的,您可以使用以下代码来实现此目的:

IntStream.range(1,myList.size())
    .forEachOrdered(i->myList.set(i,(myList.get(i)+myList.get(i-1)/2)));
System.out.println(myList);
相关问题