Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java不可变集合_Java_Collections_Immutability - Fatal编程技术网

Java不可变集合

Java不可变集合,java,collections,immutability,Java,Collections,Immutability,发件人: 不支持任何修改操作(如添加、删除和清除)的集合称为不可修改集合。[…]另外保证集合对象中的任何更改都不会可见的集合称为不可变集合 第二个标准让我有点困惑。假设第一个集合是不可修改的,并且假设原始集合引用已被丢弃,那么第二行中引用的更改是什么?它是指集合中元素的变化,即元素的状态吗 第二个问题: 对于不可变的集合,如何提供指定的额外担保?如果集合中某个元素的状态由线程更新,则在持有不可变集合的线程上,该状态下的这些更新不可见是否足以实现不变性 对于不可变的集合,如何提供指定的附加保证?不

发件人:

不支持任何修改操作(如
添加
删除
清除
)的集合称为不可修改集合。[…]另外保证集合对象中的任何更改都不会可见的集合称为不可变集合

第二个标准让我有点困惑。假设第一个集合是不可修改的,并且假设原始集合引用已被丢弃,那么第二行中引用的更改是什么?它是指集合中元素的变化,即元素的状态吗

第二个问题:
对于不可变的集合,如何提供指定的额外担保?如果集合中某个元素的状态由线程更新,则在持有不可变集合的线程上,该状态下的这些更新不可见是否足以实现不变性


对于不可变的集合,如何提供指定的附加保证?

不同之处在于,您不能引用允许更改的不可变集合。不可修改的集合通过该引用是不可修改的,但是其他一些对象可能指向可以更改它的相同数据

e、 g

List strings=new ArrayList();
列表不可修改=集合。不可修改列表(字符串);
不可修改。添加(“新字符串”);//将在运行时失败
字符串。添加(“啊哈!”);//会成功的
System.out.println(不可修改);

不可修改的集合通常是其他集合的只读视图(包装器)。您不能添加、删除或清除它们,但基础集合可以更改

不可变集合根本无法更改-它们不包装另一个集合-它们有自己的元素

这里引用了番石榴的一句话

不同于
Collections.unmodifiableList(java.util.List
Collection c1=newArrayList();
c1.添加(“foo”);
集合c2=集合。不可修改列表(c1);
c1
是可变的(即既不是不可修改的,也不是不可变的)。
c2
是不可修改的:它本身不能更改,但是如果以后我更改了
c1
,那么该更改将在
c2
中可见

这是因为
c2
只是
c1
的包装,而不是真正的独立副本。Guava提供了和一些实现。这些实现实际上是通过创建输入的副本来工作的(除非输入本身是一个不可变的集合)

关于你的第二个问题:


集合的可变性/不可变性并不取决于其中包含的对象的可变性/不可变性。修改集合中包含的对象不算作“对集合的修改”当然,如果你需要一个不可变的集合,你通常也希望它包含不可变的对象。

我认为这里的要点是,即使一个集合是不可修改的,也不能保证它不能更改。举个例子,如果一个集合太旧,它会逐出元素。不可修改只是意味着持有引用的对象无法更改它,这并不是说它无法更改。一个真实的例子是
Collections.unmodifiableList
方法。它返回列表的不可修改视图。传递到此方法的列表引用仍然是可修改的,因此传递的引用的任何持有者都可以修改列表。这可能会导致ConcurrentModificationException和其他不好的事情

不可变,意味着集合无法更改

第二个问题:不可变集合并不意味着集合中包含的对象不会更改,只是集合中包含的对象的数量和组成不会更改。换句话说,集合的引用列表不会更改。这并不意味着对象的内部被引用d不能改变。

以两种方式支持您所追求的

首先,它提供了一个
@ImmutableValue
注释,这样你就可以对一个类进行注释,说它是不可变的。有一个maven插件允许你检查你的代码实际上是不可变的(使用
final
等)

其次,它提供Clojure的持久集合(添加了泛型),并确保添加到集合中的元素是不可变的。这些元素的性能显然相当好。集合都是不可变的,但实现java集合接口(和泛型)以供检查。突变返回新集合


免责声明:我是这个

的开发人员,现在java 9具有用于不可变列表、集合、映射和映射项的工厂方法

在JavaSE8和早期版本中,我们可以使用集合类实用工具方法(如unmodifiableXXX)来创建不可变的集合对象

但是,这些Collections.unmodifiableXXX方法非常繁琐。为了克服这些缺点,Oracle corp添加了两种实用方法来列出、设置和映射接口

现在使用java 9:- List和Set接口具有“of()”方法来创建空的或不空的不可变列表或Set对象,如下所示:

空列表示例

List immutableList = List.of();
List immutableList = List.of("one","two","three");
非空列表示例

List immutableList = List.of();
List immutableList = List.of("one","two","three");
通常(特别是在函数式语言中),不可变(也称为持久)集合可能会发生变化,因为您可以获取此集合的新状态,但同时旧状态仍可以从其他链接获得。例如,
newCol=oldCol.add(“元素”)
将生成一个新的集合,该集合是旧集合的副本,包含1个元素,并且对
旧集合的所有引用仍将指向同一个未更改的旧集合。@John:否