Java不可变列表的示例

时间:2020-01-09 10:35:02  来源:igfitidea点击:

在Java 9中,在Java中添加了不可变集合,这使得创建不可变的List,Set或者Map变得容易。在本文中,我们将介绍如何在Java中使用不可变列表。

一旦创建了一个不可变的列表,就不能添加,删除或者替换元素。调用List上的任何mutator方法将始终引发UnsupportedOperationException。

在Java 9之前创建不可变列表

在Java 9之前,创建不可变列表的唯一方法是使用Collections.unmodifiableList(List <?extended T> list)方法。
这是一个示例,显示了如何在Java 9之前创建不可修改的列表。在该程序中,我们可以看到仍可以更改原始列表(已向其中添加了新元素)。另一方面,无法修改的列表实例无法进行更改。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ImmutList {
  public static void main(String[] args) {
    List<String> numList = new ArrayList<>();
    numList.add("1");
    numList.add("2");
    numList.add("3");
    numList.add("4");
    // Creating Immutable List
    List<String> anotherList = Collections.unmodifiableList(numList);
    numList.add("5");
    System.out.println("Number List- " + numList);
    // This throws exception
    anotherList.add("6");
  }
}

输出:

Number List- [1, 2, 3, 4, 5]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1058)
	at com.theitroad.proj.Programs.ImmutList.main(ImmutList.java:18)

做到这一点的另一种方法是使用Arrays.asList()方法,该方法不太冗长。

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ImmutList {
  public static void main(String[] args) {
    List<String> numList = Arrays.asList("1", "2", "3", "4");
    // Creating Immutable List
    List<String> anotherList = Collections.unmodifiableList(numList);
    numList.add("5");
    System.out.println("Number List- " + numList);
    // This throws exception
    anotherList.add("6");
  }
}

使用这种方法,即使在原始列表元素中也无法添加。

向前创建不可变列表Java 9

从Java 9开始,有两种静态工厂方法,它们提供了一种创建不可修改列表的便捷方法。

  • List.of(在Java 9中添加)
  • List.copyOf(在Java 10中添加)

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

  • 它们是不可修改的。元素无法添加,删除或者替换。调用List上的任何mutator方法将始终引发UnsupportedOperationException。但是,如果所包含的元素本身是可变的,则可能导致列表的内容似乎发生变化。
  • 空元素不能添加到不可变列表中。尝试使用null元素创建它们会导致NullPointerException。
  • 如果所有元素都是可序列化的,则它们是可序列化的。
  • 列表中元素的顺序与提供的参数或者提供的数组中的元素的顺序相同。

List.of方法示例

List.of()静态方法同时具有固定参数形式和varargs形式。

固定参数形式提供了创建0到10个元素的列表的选项,这些方法的形式如下。

of()- Returns an unmodifiable list containing zero elements.
of(E e1)- Returns an unmodifiable list containing one element.
of(E e1, E e2)	Returns an unmodifiable list containing two elements.
..
..
of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)- Returns an unmodifiable list containing nine elements.
of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)- Returns an unmodifiable list containing ten elements.

添加任意数量的元素的方法(变量)

of(E... elements)- Returns an unmodifiable list containing an arbitrary number of elements.
import java.util.List;

public class ImmutList {
  public static void main(String[] args) {
    List<String> numList = List.of("1", "2", "3", "4");    
    System.out.println("Number List- " + numList);
    // Throws exception
    numList.add("5");
  }
}

List.copyOf方法示例

使用copyOf()方法,我们可以使用现有集合创建不可变列表。如果后来修改了用于创建不可变列表的Collection,则返回的List将不会反映此类修改。

import java.util.ArrayList;
import java.util.List;

public class ImmutList {
  public static void main(String[] args) {
    List<String> numList = new ArrayList<>();
    numList.add("1");
    numList.add("2");
    numList.add("3");
    numList.add("4");
    List<String> iList = List.copyOf(numList);    
    System.out.println("Immutable List- " + iList);
    // change original collection
    numList.add("5");
    System.out.println("Immutable List- " + iList);
  }
}

输出:

Immutable List- [1, 2, 3, 4]
Immutable List- [1, 2, 3, 4]

如我们所见,后来创建了用于创建不可变列表的numList,但该更改未反映在不可变列表中。