gpt4 book ai didi

Java 8 lambda表达式多次更改Collection

转载 作者:行者123 更新时间:2023-12-01 22:20:11 26 4
gpt4 key购买 nike

我有以下类(class):

Doer,它只执行 Runnable 的运行方法(将是一个 lambda):

public class Doer {
final Runnable runnable;

public Doer(final Runnable runnable) {
this.runnable = runnable;
}

public void doSomething() {
runnable.run();
}
}

存储,这是一个可观察的数字存储:

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;

public class Storage extends Observable {
final List<Integer> storage;

public Storage() {
this.storage = new ArrayList<>();
}

void add(int number) {
storage.add(number);
setChanged();
notifyObservers(number);
}

public List<Integer> getStorage() {
return storage;
}
}

过滤,防止行动者做太多事情;)

import java.util.Observable;
import java.util.Observer;

public class Filter implements Observer {

final Doer doer;
int counter;
final int nth;

public Filter(int nth, Storage store, Doer doer) {
this.doer = doer;
this.nth = nth;
store.addObserver(this);
}

@Override
public void update(Observable o, Object arg) {
counter++;
if (counter == nth)
doer.doSomething();
}
}

现在考虑以下单元测试:

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class FilterTest {

@Test
public void testStore() throws Exception {
List<Collection<Integer>> numbers = new ArrayList<>();
Storage store = new Storage();
Filter filter = new Filter(2, store, new Doer(() -> {
numbers.add(store.getStorage());
System.out.println(numbers);
}));

System.out.println(numbers);

store.add(1);
System.out.println(numbers);

store.add(2);
System.out.println(numbers);

store.add(3);

System.out.println(numbers);

}
}

它产生的结果:

[]
[]
[[1, 2]]
[[1, 2]]
[[1, 2, 3]]

我真的不明白最后一行,为什么 3 现在是数字,因为 number.add(3) 尚未在 lambda 中执行?

最佳答案

lambda 仅被调用一次。它添加了 List<Integer>就在里面storenumbers .

请注意,lambda 并未复制 List<Integer>store 。所以,numbers包含对相同 List<Integer> 的引用就像 store 中的内容一样.

如果您向 List<Integer> 添加更多数字在store ,您也会在 numbers 中看到这些更改,因为 numbers 的内容是对相同 List<Integer> 的引用.

所以当你这样做时store.add(3);然后打印numbers的内容,您还会看到 3在那里。

将集合添加到 numbers 时尝试创建该集合的副本在 lambda 中,看看差异:

Filter filter = new Filter(2, store, new Doer(() -> {
numbers.add(new ArrayList<>(store.getStorage()));
System.out.println(numbers);
}));

输出:

[]
[]
[[1, 2]]
[[1, 2]]
[[1, 2]]

关于Java 8 lambda表达式多次更改Collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30017894/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com