【问题标题】:Are Java 8 streams immutable?Java 8 流是不可变的吗?
【发布时间】:2020-05-25 14:46:50
【问题描述】:

如果我的 API 提供流,客户端是否可以修改底层集合?

例如:

class ListWrapper {
  List<String> myList;
  ...
  Stream<String> getStream() {
    return myList.stream();
  }
}

客户端是否可以调用listWrapper.getStream() 并以某种方式修改myList 的内容?

【问题讨论】:

  • 修改myList的结构还是修改其中的各个元素?
  • 要么。我想知道客户是否可以以任何方式更改 myList(例如更改元素的顺序,或更改任何给定元素的内容)。
  • 这个问题略有不同。我相信这个问题假设客户端可以访问底层源集合(例如myList)。这个问题询问的是向客户端公开流的可变性风险。

标签: java java-stream immutability


【解决方案1】:

流不能修改底层集合(如果集合本身没有公开),因此不能添加或删除元素,也不能更改顺序。当您在终端操作中使用流时,会构建一个新集合(但您可以将其收集到另一个现有集合中)。

但是,如果元素本身是可变的,流操作仍然可以修改单个元素。这是不好的做法,但可以做到。

例子:

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(或countforEach或任何其他终端操作)消费时,peek回调将修改每个元素。运行上述代码后,您的列表将包含 2 个值为 x=3 的项目。 peek 是任意选择的非终端操作。使用filtermap/flatMap 或任何其他非终端操作可以观察到相同的行为。

在本质上,这与:Is Java "pass-by-reference" or "pass-by-value"? 非常相似,但隐藏得更好。

【讨论】:

    猜你喜欢
    • 2017-02-14
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 2014-05-04
    相关资源
    最近更新 更多