Java 如何创建不可变集合

如何使用 Java 9 中的新工厂方法创建不可变集合,例如不可变列表、不可变集合和不可变映射?

创建不可变列表

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

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实例具有以下特点:

  • 这些列表是不可变的。不能在这些列表中添加、删除或者替换元素。调用任何 mutator 方法(即 add、addAll、clear、remove、removeAll、replaceAll)都会导致抛出 UnsupportedOperationException
  • 它们不允许 null元素。尝试添加 null元素会导致 NullPointerException
  • 如果所有元素都可序列化,则它们是可序列化的。
  • 列表中元素的顺序与提供的参数或者提供的数组中元素的顺序相同。

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

package com.onitroad;
import java.util.List;
public class ImmutableCollections 
{
    public static void main(String[] args) 
    {
        List<String> names = List.of("JackLi", "cherry", "John");

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

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

        //java.lang.NullPointerException
        //List<String> names2 = List.of("JackLi", "cherry", "John", null); 
    }
}
Output:
[JackLi, cherry, John]

创建不可变映射

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

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 条目实例。

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

让我们以在 java 9 中创建不可变的 Map为例。

import java.util.Map;
public class ImmutableCollections {
    public static void main(String[] args) {
        Map<String, String> names = Map.ofEntries(
                Map.entry("1", "JackLi"),
                Map.entry("2", "cherry"),
                Map.entry("3", "BobRobert"));

        System.out.println(names);

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

显然,在 Java 9 中创建不可变集合的新工厂方法非常易读且易于使用。

www. On IT Road .com

创建不可变集

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

  • Set也不允许重复元素。

传递的任何重复元素都将导致“IllegalArgumentException”。

  • 集合元素的迭代顺序未指定并且可能会发生变化。

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

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)

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

import java.util.Set;
public class ImmutableCollections {
    public static void main(String[] args) {
        Set<String> names = Set.of("JackLi", "cherry", "John");

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

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

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

        //java.lang.IllegalArgumentException
        //Set<String> names3 = Set.of("JackLi", "cherry", "John", "cherry"); 
    }
}
日期:2020-09-17 00:09:46 来源:oir作者:oir