Java 9集合相关变更

前言

Java 9 对于不可变集合可以使用工厂模式进行创建,我们来看一下,如何来创建不可变List、不可变Map、不可变Set。

正文

创建不可变List(Immutable List)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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. 这些List是不可变的。在这些List中不能添加、删除或替换元素。调用任何mutator方法(即addaddAllclearremoveremoveAllreplaceAll)总是会引发UnsupportedOperationException
  2. 它们不允许空元素。尝试添加空元素会导致NullPointerException
  3. 如果所有元素都是可序列化的,则它们是可序列化的。
  4. 列表中元素的顺序与提供的参数或提供的数组中的元素的顺序相同。

让我们来看几个使用不可变列表的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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(Immutable Set)

Set的行为与List非常相似,只有很少的区别。如:

  1. 设置不允许重复的元素。传递的任何重复元素都会导致IllegalArgumentException
  2. 集合元素的迭代顺序是未指定的,可能会发生变化。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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(Immutable Map)

Map工厂方法与ListSet重载工厂方法相同。唯一的区别是方法的签名采用交替的键和值作为参数。如下:

1
2
3
4
5
6
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实例。

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

我们来看几个Java 9 创建不可变Map的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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中创建不可变集合的新工厂方法非常易读且易于使用。




-------------文章结束啦 ~\(≧▽≦)/~ 感谢您的阅读-------------

您的支持就是我创作的动力!

欢迎关注我的其它发布渠道