如果我的API提供了一个流,客户是否有办法修改底层集合?
例如,我的API提供了一个流,客户是否有办法修改底层的集合?
class ListWrapper {
List<String> myList;
...
Stream<String> getStream() {
return myList.stream();
}
}
客户端是否可以调用 listWrapper.getStream()
的内容,并以某种方式修改 myList
?
一个流不能修改底层的集合(如果集合本身没有暴露的话),所以不能添加或删除元素,也不能改变顺序。当你在终端操作中消耗一个流时,会建立一个新的集合(但你可以收集到另一个现有的集合)。
然而,仍然有可能的是,如果元素本身是不可改变的,流操作可以修改单个元素。这是不好的做法,但可以做到。
举个例子。
class Item { public int x; public Item(int x) { this.x = x; } }
var list = List.of(new Item(1), new Item(2));
list.stream().peek(item -> item.x = 3).collect(toList());
当流被消耗了 collect
(或 count
或 forEach
或任何其他终端操作),该 peek
回调将修改每个元素。运行上述代码后,您的列表将包含2个值为 x=3
. peek
是一个任意选择的非终端操作。同样的行为可以在 filter
, map
flatMap
或任何其他非终端操作。
在精神上,这与。Java是 "按引用传递 "还是 "按值传递"?,只是隐蔽性更好一些。