# Java 9 中的不可变集合和工厂方法

> 原文： [https://howtodoinjava.com/java9/create-immutable-collections-factory-methods/](https://howtodoinjava.com/java9/create-immutable-collections-factory-methods/)

学习使用新的[创建](//howtodoinjava.com/design-patterns/creational/implementing-factory-design-pattern-in-java/)**[不可变](//howtodoinjava.com/java/basics/how-to-make-a-java-class-immutable/)集合**，例如*不可变列表*，*不可变集*和*不可变映射* Java 9 中的工厂方法。

```java
Table of Contents

Create Immutable List
Create Immutable Set
Create Immutable Map
```

## 创建不可变列表

使用`List.of()`静态工厂方法创建不可变列表。 它具有以下不同的重载版本：

```java
static <E> List<E>	of()
static <E> List<E>	of(E e1)
static <E> List<E>	of(E e1, E e2)
static <E> List<E>	of(E e1, E e2, E e3)
static <E> List<E>	of(E e1, E e2, E e3, E e4)
static <E> List<E>	of(E e1, E e2, E e3, E e4, E e5)
static <E> List<E>	of(E e1, E e2, E e3, E e4, E e5, E e6)
static <E> List<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
static <E> List<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
static <E> List<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
static <E> List<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
//varargs
static <E> List<E>	of(E... elements)
```

这些方法创建的`List`实例具有以下特征：

1.  这些列表是不可变的。 不能在这些列表中添加，删除或替换元素。 调用任何可变方法（即`add`，`addAll`，`clear`，`remove`，`removeAll`，`replaceAll`）将始终导致抛出`UnsupportedOperationException`。
2.  它们不允许`null`元素。 尝试添加`null`元素将导致`NullPointerException`。
3.  如果所有元素都是可序列化的，它们可以[可序列化的](//howtodoinjava.com/java/serialization/a-mini-guide-for-implementing-serializable-interface-in-java/)。
4.  列表中元素的顺序与提供的参数或提供的数组中的元素的顺序相同。

让我们看一些使用不可变列表的例子。

```java
package com.howtodoinjava;

import java.util.List;

public class ImmutableCollections 
{
    public static void main(String[] args) 
    {
        List<String> names = List.of("Lokesh", "Amit", "John");

        //Preserve the elements order
        System.out.println(names);

        //names.add("Brian"); //UnsupportedOperationException occured

        //java.lang.NullPointerException
        //List<String> names2 = List.of("Lokesh", "Amit", "John", null); 
    }
}

Output:

[Lokesh, Amit, John]

```

## 创建不可变集

`Set`的行为与`List`非常相似，只是差异很小。 例如：

1.  `Set`也不允许[重复元素](//howtodoinjava.com/puzzles/find-duplicate-elements-in-an-array/)。 传递的任何重复元素将导致`IllegalArgumentException`。
2.  集合元素的迭代顺序未指定，可能会发生变化。

所有`Set`工厂方法都具有与`List`相同的签名。

```java
static <E> Set<E>	of()
static <E> Set<E>	of(E e1)
static <E> Set<E>	of(E e1, E e2)
static <E> Set<E>	of(E e1, E e2, E e3)
static <E> Set<E>	of(E e1, E e2, E e3, E e4)
static <E> Set<E>	of(E e1, E e2, E e3, E e4, E e5)
static <E> Set<E>	of(E e1, E e2, E e3, E e4, E e5, E e6)
static <E> Set<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
static <E> Set<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
static <E> Set<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
static <E> Set<E>	of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
//varargs
static <E> Set<E>	of(E... elements)
```

我们来看几个不可变集的例子。

```java
import java.util.Set;

public class ImmutableCollections {
    public static void main(String[] args) {
        Set<String> names = Set.of("Lokesh", "Amit", "John");

        //Elements order not fixed
        System.out.println(names);

        //names.add("Brian"); //UnsupportedOperationException occured

        //java.lang.NullPointerException
        //Set<String> names2 = Set.of("Lokesh", "Amit", "John", null); 

        //java.lang.IllegalArgumentException
        //Set<String> names3 = Set.of("Lokesh", "Amit", "John", "Amit"); 
    }
}

```

## 创建不可变映射

`Map`工厂方法与`List`或`Set`重载工厂方法相同。 唯一的区别是方法的签名采用交替的键和值作为参数。 例如：

```java
static <K,V> Map<K,V>	of()
static <K,V> Map<K,V>	of(K k1, V v1)
static <K,V> Map<K,V>	of(K k1, V v1, K k2, V v2)
...
...
static <K,V> Map<K,V>	ofEntries(Map.Entry<? extends K,? extends V>... entries)
```

Java 9 还提供了一种特殊的方法来创建 Map 条目实例。

```java
static <K,V> Map.Entry<K,V>	entry​(K k, V v)
```

让我们举一个在 Java 9 中创建不可变`Map`的示例。

```java
import java.util.Map;

public class ImmutableCollections {
    public static void main(String[] args) {
        Map<String, String> names = Map.ofEntries(
                Map.entry("1", "Lokesh"),
                Map.entry("2", "Amit"),
                Map.entry("3", "Brian"));

        System.out.println(names);

        //UnsupportedOperationException
        //names.put("2", "Ravi");
    }
}

Output:

{1=Lokesh, 2=Amit, 3=Brian}

```

显然，在 Java 9 中创建不可变集合的新**工厂方法具有很高的可读性和易用性**。

请在评论部分中将您对这些不可变集合的观点放下。

学习愉快！