1.简介
在本教程中, 我们将了解在Java中构造不可变集的不同方法。
但首先,让我们理解不可变集,看看为什么我们需要它。
2.什么是不可变集?
通常, 一旦创建它 , 一个 不可变对象 就不会改变它的内部状态。 这使它在默认情况下是 线程安全 的。相同的逻辑适用于不可变集。
假设我们有一个带有一些值的HashSet实例。使其不可变将创建我们的集合的”只读”版本。因此, 任何修改其状态的尝试都将抛出 UnsupportedOperationException 。
那么,为什么我们需要呢?
当然,不可变集的最常见用例是 多线程 环境。因此,我们可以跨线程共享不可变数据,而不必担心同步。
同时,要记住一个重点: 不变性只与集合有关,而与其元素无关 。此外,我们可以毫无问题地修改set元素的实例引用。
3.在Core Java中创建不可变集
只有我们可以使用的核心Java类,我们可以使用 集合 。 unmodifiableSet() 方法包装原始 Set 。
首先,让我们创建一个简单的HashSet实例并使用 String 值初始化它:
Set<String> set = new HashSet<>(); set.add( "Canada" ); set.add( "USA" );
接下来,让我们用 Collections 将其包装起来 。 unmodifiableSet(): Set<String> unmodifiableSet = Collections.unmodifiableSet(set);
最后,为了确保我们的 unmodifiableSet 实例是不可变的,让我们创建一个简单的 测试用例 :
@Test (expected = UnsupportedOperationException. class ) public void testUnmodifiableSet() { // create and initialize the set instance Set<String> unmodifiableSet = Collections.unmodifiableSet(set); unmodifiableSet.add( "Costa Rica" ); }
正如我们所料,测试将成功运行。此外, unmodifiableSet 实例上禁止 add() 操作,并将抛出 UnsupportedOperationException 。
现在,让我们 通过向它添加相同的值来更改初始 集 实例:
set.add( "Costa Rica" );
这样,我们间接修改了不可修改的集合。所以,当我们打印 unmodifiableSet 实例时: [Canada, USA, Costa Rica]
我们可以看到, “哥斯达黎加” 项目也存在于 unmodifiableSet中。
4.在Java 9中创建不可变集
从Java 9开始, Set.of(elements) 静态工厂方法可用于创建不可变集:
Set<String> immutable = Set.of( "Canada" , "USA" );
5.在Guava中创建不可变集
我们可以构造一个不可变集的另一种方法是使用Guava的 ImmutableSet 类 。它将现有数据复制到新的不可变实例中。因此, 当我们更改原始 Set 时, ImmutableSet中 的数据不会更改。
与核心Java实现一样,任何修改创建的不可变实例的尝试都将抛出 UnsupportedOperationException 。
现在,让我们探索创建不可变实例的不同方法。
5.1。使用 ImmutableSet.copyOf()
简单地说,就是 ImmutableSet 。 copyOf() 方法返回集合中所有元素的副本: Set<String> immutable = ImmutableSet.copyOf(set);
因此,在更改初始集之后,不可变实例将保持不变: [Canada, USA]
5.2。使用ImmutableSet .of()
类似地,使用 ImmutableSet.of()方法,我们可以立即创建具有给定值的不可变集:
Set<String> immutable = ImmutableSet.of( "Canada" , "USA" );
当我们不指定任何元素时, ImmutableSet.of() 将返回一个空的不可变集。
这可以与Java 9的 Set .of()进行比较。
6 总结
在这篇快速文章中,我们讨论了Java语言中的不可变 集合 。 此外,我们展示了如何 使用核心Java,Java 9和Guava库中的Collections API 创建不可变 集合 。
详情: