1. 程式人生 > >Java 9 揭祕(13. Collection API 更新)

Java 9 揭祕(13. Collection API 更新)

Tips
做一個終身學習的人。

Java 9

在本章中,主要介紹以下內容:

  • 在JDK 9之前如何建立了不可變的list,set和map以及使用它們的問題。
  • 如何使用JDK 9中的List介面的of()靜態工廠方法建立不可變的list。
    如何使用JDK 9中的Set介面的of()靜態工廠方法建立不可變的set。
    如何使用JDK 9中的Map介面的of()ofEntries()entry()靜態工廠方法建立不可變的map。

一. 背景

Collection API由類和介面組成,提供了一種儲存和操作不同型別的物件集合的方法,例如list,set和map。 它在Java SE 1.2版本中新增進來。 Java程式語言不支援

Collection Literals,這是一種簡單易用的方式來宣告和初始化集合。 Collection Literals允許通過在緊湊形式的表示式中指定集合的元素來建立特定型別的集合。 Collection Literals的一個示例是一個列表文字,能夠建立一個列表,其中包含100和200的整數,如下所示:

List<Integer> list = [100, 200];

Collection Literals緊湊,使用簡單。 由於在建立時已知元素的數量,因此可以實現高效的記憶體使用。 它可以設計成不可變的,使其執行緒安全。

在Java程式語言中包含Collection Literals語法在JDK 9之前被考慮過幾次。 Java設計師決定不將Collection Literals新增到Java語言中,至少不在JDK 9中。在這一點上將Collection Literals新增到Java將需要太多的努力來獲得太少的收益。 他們決定通過在List

SetMap介面中新增靜態工廠方法來更新Collection API,從而可以輕鬆有效地建立小型的,不可變的集合來實現相同的目標。

現有的Collection API建立可變集合。 可以通過將可變集合包裝在另一個物件中建立一個不可變的(或不可修改的)集合,該物件只是原始可變物件的包裝器。 要在JDK 8或更早版本中建立兩個整數的無法修改的列表,通常使用以下程式碼片段:

// Create an empty, mutable list
List<Integer> list = new ArrayList<>();
// Add two elements to the mutable list
list.add(100);
list.add(200);
// Create an immutable list by wrapping the mutable list
List<Integer> list2 = Collections.unmodifiableList(list);

這種做法有嚴重的缺陷。 不可變的list只是可修改list的包裝。 有意的是,將變數名為list。 不能使用list2變數修改列表。但是,仍然可以使用list變數來修改列表,並且在使用list2變數讀取list時將會反映出修改。 下面包含一個完整的程式來建立一個不可變的list,並顯示如何在以後更改其內容。

// PreJDK9UnmodifiableList.java
package com.jdojo.collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PreJDK9UnmodifiableList {
    public static void main(String[] args) {
       List<Integer> list = new ArrayList<>();
       list.add(100);
       list.add(200);
       System.out.println("list = " + list);
       // Create an unmodifiable list
       List<Integer> list2 = Collections.unmodifiableList(list);
       System.out.println("list2 = " + list2);
       // Let us add an element using list
       list.add(300);
       // Print the contents of the list using both
       // variables named list and list2
       System.out.println("list = " + list);
       System.out.println("list2 = " + list2);
    }  
}

輸出結果為:

list = [100, 200]
list2 = [100, 200]
list = [100, 200, 300]
list2 = [100, 200, 300]

輸出顯示,只要保留原始列表的引用,就可以更改其內容,並且不可變的list也不是真正不可變的! 解決此問題的方法是使用新的不可變list引用來覆蓋原始引用變數,如下所示:

List<Integer> list = new ArrayList<>();
list.add(100);
list.add(200);
// Create an unmodifiable list and store it in list
list = Collections.unmodifiableList(list);

注意,此示例使用多個語句來建立和填入不可變的list。 如果需要在類中宣告和初始化不可變的list作為例項或靜態變數,則該方法不起作用,因為它涉及多個語句。 這樣一個宣告需要簡單,緊湊,並且包含在一個宣告中。 如果在類中使用以前的程式碼來例項變數,那麼程式碼將類似於以下程式碼:

public class Test {
    private List<Integer> list = new ArrayList<>();
    {
       list.add(100);
       list.add(200);
       list = Collections.unmodifiableList(list);
    }
    // ...
}

還有其他方式來宣告和初始化一個不可變的list,例如使用陣列並將其轉換為list。 其中三種方式如下:

public class Test {
    // Using an array and converting it to a list
    private List<Integer> list2 = Collections.unmodifiableList(           new ArrayList<>( Arrays.asList(100, 200)));
    // Using an anonymous class
    private List<Integer> list3 = Collections.unmodifiableList(           new ArrayList<>(){{add(100); add(200);}});
    // Using a stream
    private List<Integer> list4 = Collections.unmodifiableList(           Stream.of(100, 200).collect(Collectors.toList()));
    // More code goes here
}

此示例證明可以在一個語句中具有不可變的list。 但是,語法是冗長的。 再是效率低下。 例如,只要在list中儲存兩個整數,則需要建立具有後備陣列物件的多個物件來儲存這些值。

JDK 9通過向ListSetMap介面提供靜態工廠方法來解決這些問題。 該方法命名為of()並且被過載。 在JDK 9中,可以宣告和初始化兩個元素的不可變列表,如下所示:

// Create an unmodifiable list of two integers
List<Integer> list = List.of(100, 200);

二. 不可變的list

JDK 9將of()靜態工廠方法過載到List介面。 它提供了一種簡單而緊湊的方式來建立不可變的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)
static <E> List<E> of(E... elements)

of()方法有11個特定版本來建立零到十個元素的list。 另一個版本採用可變引數來允許建立任何數量的元素的不可變的list。 你可能會想知道當使用可變引數的版本可以建立具有任意數量的元素的列表時,為什麼有這麼多版本的方法。 它們存在為效能原因。 API設計人員希望能夠有效地使用少量元素的列表。 使用陣列實現可變引數。 存在具有非可變引數的方法,以避免將引數裝入陣列中,這使得它們更有效率。 這些方法使用List介面的特殊實現類用於較小的list。

of()方法返回的list具有以下特徵:

  • 結構上是不可變的。 嘗試新增,替換或刪除元素會丟擲UnsupportedOperationException異常。
  • 不允許null元素。 如果列表中的元素為null,則丟擲NullPointerException異常。
  • 如果所有元素是可序列化的,那麼它們也是可序列化的。
  • 元素的順序與of()方法中指定的,與of(E… elements)方法的可變引數版本中使用的陣列相同。
  • 對返回的列表的實現類沒有保證。 也就是說,不要指望返回的物件是ArrayList或任何其他實現List介面的類。 這些方法的實現是內部的,不應該假定他們的類名。 例如,List.of()List.of("A")可能會返回兩個不同類的物件。

Collections類包含一個EMPTY_LIST的靜態屬性,表示不可變的空list。 它還包含一個emptyList()的靜態方法來獲取不可變的空list。singletonList(T object)方法返回具有指定元素的不可變單例list。 以下程式碼片段顯示了JDK 9和JDK 9之前建立不可變的空和單例list的方式。

// Creating an empty, immutable List before JDK 9
List<Integer> emptyList1 = Collections.EMPTY_LIST;
List<Integer> emptyList2 = Collections.emptyList();
// Creating an empty list in JDK 9
List<Integer> emptyList = List.of();
// Creating a singleton, immutable List before JDK 9
List<Integer> singletonList1 = Collections.singletonList(100);
// Creating a singleton, immutable List in JDK 9
List<Integer> singletonList = List.of(100);

如何使用of()方法從陣列中建立一個不可變的list? 答案取決於你想要從陣列的列表。 可能需要一個list,其元素與陣列的元素相同,或者可能希望使用陣列本身作為列表中唯一元素的list。 使用List.of(array)將呼叫of(E... elements)方法,返回的列表將其元素與陣列中的元素相同。 如您希望陣列本身是list中的唯一元素,則需要使用List.<array-type>of(array)方法,這將呼叫of(E e1)方法,返回的列表將具有一個 元素,它是陣列本身。 以下程式碼使用Integer陣列來演示:

Integer[] nums = {100, 200};
// Create a list whose elements are the same as the elements
// in the array
List<Integer> list1 = List.of(nums);        
System.out.println("list1 = " + list1);
System.out.println("list1.size() = " + list1.size());
// Create a list whose sole element is the array itself
List<Integer[]> list2 = List.<Integer[]>of(nums);        
System.out.println("list2 = " + list2);
System.out.println("list2.size() = " + list2.size());

輸出結果為:

list1 = [100, 200]
list1.size() = 2
list2 = [[Ljava.lang.Integer;@27efef64]
list2.size() = 1

下面包含一個完整的程式,顯示如何使用List介面的of()靜態工廠方法來建立不可變的list。

// ListTest.java
package com.jdojo.collection;
import java.util.List;
public class ListTest {
    public static void main(String[] args) {
        // Create few unmodifiable lists
        List<Integer> emptyList = List.of();
        List<Integer> luckyNumber = List.of(19);
        List<String> vowels = List.of("A", "E", "I", "O", "U");
        System.out.println("emptyList = " + emptyList);
        System.out.println("singletonList = " + luckyNumber);
        System.out.println("vowels = " + vowels);
        try {
            // Try using a null element
            List<Integer> list = List.of(1, 2, null, 3);
        } catch(NullPointerException e) {
            System.out.println("Nulls not allowed in List.of().");
        }
        try {
            // Try adding an element
            luckyNumber.add(8);
        } catch(UnsupportedOperationException e) {
            System.out.println("Cannot add an element.");
        }
        try {
            // Try removing an element
            luckyNumber.remove(0);
        } catch(UnsupportedOperationException e) {
            System.out.println("Cannot remove an element.");
        }
    }
}

輸出結果為:

emptyList = []
singletonList = [19]
vowels = [A, E, I, O, U]
Nulls not allowed in List.of().
Cannot add an element.
Cannot remove an element .

三. 不可變的set

JDK 9在Set介面中添加了of()靜態工廠方法的過載。 它提供了一種簡單而緊湊的方式來建立不可變的set。 以下是of()方法的所有版本:

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)
static <E> Set<E> of(E... elements)

of()方法的所有版本為效能都做了調整。 可以使用前11個版本來建立一個不可變的零到十個元素的set。 of方法的前11個版本與可變引數的版本一起存在的原因是為了避免將引數裝入陣列中,最多可設定10個元素。 可變引數的版本可用於建立一個包含任意數量元素的不可變set。

of()方法返回的set具有以下特徵:

  • 結構上是不可變的。 嘗試新增,替換或刪除元素會丟擲UnsupportedOperationException異常。
  • 不允許null元素。 如果set中的元素為null,則丟擲NullPointerException異常。
  • 如果所有元素是可序列化的,那麼它們是可序列化的。
  • 不允許重複元素。 指定重複的元素會引發一個IllegalArgumentException
  • 元素的迭代順序是未指定的。
  • 對於返回的集合的實現類不能保證。 也就是說,不要指望返回的物件是HashSet或任何其他實現Set介面的類。 這些方法的實現是內部的,不應該假定他們的類名。 例如,Set.of()Set.of(“A”)可能返回兩個不同類的物件。

Collections類包含一個EMPTY_SET的靜態屬性,表示不可變的空set。 它還包含emptySet()的靜態方法來獲取不可變的空set。 它的singleton(T object)方法返回具有指定元素的不可變單例set。 以下程式碼片段顯示了JDK 9和JDK 9之前建立不可變的空和單例set的方法:

// Creating an empty, immutable Set before JDK 9
Set<Integer> emptySet1 = Collections.EMPTY_SET;
Set<Integer> emptySet2 = Collections.emptySet();
// Creating an empty Set in JDK 9
Set<Integer> emptySet = Set.of();
// Creating a singleton, immutable Set before JDK 9
Set<Integer> singletonSet1 = Collections.singleton(100);
// Creating a singleton, immutable Set in JDK 9
Set<Integer> singletonSet = Set.of(100);

以下程式碼顯示瞭如何從陣列中建立一個不可變的set。 可以有一個set的元素與陣列的元素相同,或者可以使用集合作為唯一元素的集合。 注意,當使用陣列元素作為集合的元素時,該陣列不能具有重複的元素。 否則,Set.of()方法將丟擲IllegalArgumentException異常。

Integer[] nums = {100, 200};
// Create a set whose elements are the same as the
// elements of the array
Set<Integer> set1 = Set.of(nums);
System.out.println("set1 = " + set1);
System.out.println("set1.size() = " + set1.size());
// Create a set whose sole element is the array itself
Set<Integer[]> set2 = Set.<Integer[]>of(nums);
System.out.println("set2 = " + set2);
System.out.println("set2.size() = " + set2.size());
// Create an array with duplicate elements
Integer[] nums2 = {101, 201, 101};
// Try creating a set with the array as its sole element
Set<Integer[]> set3 = Set.<Integer[]>of(nums2);
System.out.println("set3 = " + set3);
System.out.println("set3.size() = " + set3.size());
try {
    // Try creating a set whose elements are the elements of
    // the array. It will throw an IllegalArgumentException.
    Set<Integer> set4 = Set.of(nums2);
    System.out.println("set4 = " + set4);
} catch(IllegalArgumentException e) {
    System.out.println(e.getMessage());
}

輸出結果為:

set1 = [100, 200]
set1.size() = 2
set2 = [[Ljava.lang.Integer;@47c62251]
set2.size() = 1
set3 = [[Ljava.lang.Integer;@3e6fa38a]
set3.size() = 1
duplicate element: 101

下面包含一個完整的程式,顯示如何使用Set介面的of()靜態工廠方法來建立不可變的set。 注意程式中包含母音元素的set的輸出。 組合的元素可能不會以建立set時指定的相同順序輸出,因為set不保證其元素的順序。

// SetTest.java
package com.jdojo.collection;
import java.util.Set;
public class SetTest {
    public static void main(String[] args) {
        // Create few unmodifiable sets
        Set<Integer> emptySet = Set.of();
        Set<Integer> luckyNumber = Set.of(19);
        Set<String> vowels = Set.of("A", "E", "I", "O", "U");
        System.out.println("emptySet = " + emptySet);
        System.out.println("singletonSet = " + luckyNumber);
        System.out.println("vowels = " + vowels);
        try {
            // Try using a null element
            Set<Integer> set = Set.of(1, 2, null, 3);
        } catch(NullPointerException e) {
            System.out.println("Nulls not allowed in Set.of().");
        }
        try {
            // Try using duplicate elements
            Set<Integer> set = Set.of(1, 2, 3, 2);
        } catch(IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
        try {
            // Try adding an element
            luckyNumber.add(8);
        } catch(UnsupportedOperationException e) {
            System.out.println("Cannot add an element.");
        }
         try {
            // Try removing an element
            luckyNumber.remove(0);
        } catch(UnsupportedOperationException e) {
            System.out.println("Cannot remove an element.");
        }
    }
}

以下是輸出結果:

emptySet = []
singletonSet = [19]
vowels = [E, O, A, U, I]
Nulls not allowed in Set.of().
duplicate element: 2
Cannot add an element.
Cannot remove an element.

四. 不可變的map

JDK 9將of()靜態工廠方法過載添到Map介面中。 它提供了一種簡單而緊湊的方式來建立不可變的map。 方法的實現為效能做了調整。 以下是of()方法的11個版本,可以建立一個不可變的零到十個鍵值條目的map:

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> of(K k1, V v1, K k2, V v2, K k3, V v3)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10)

注意在of()方法中的引數的位置。 第一個和第二個引數分別是map中第一個鍵值對的鍵和值;第三個和第四個引數分別是map中第二個鍵值對的鍵和值。 注意,在Map中,沒有像在ListSet中可變引數的of()方法。 這是因為Map條目包含兩個值(鍵值和值),並且Java中的方法中只能有一個可變引數。 以下程式碼片段顯示瞭如何使用of()方法建立map:

// An empty, unmodifiable Map
Map<Integer, String> emptyMap = Map.of();
// A singleton, unmodifiable Map
Map<Integer, String> singletonMap = Map.of(1, "One");
// A unmodifiable Map with two entries
Map<Integer, String> luckyNumbers = Map.of(1, "One", 2, "Two");

要建立具有任意數量條目的不可修改的Map,JDK 9在Map介面中提供了一個ofEntries()的靜態方法,它的簽名如下:

<K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)

要使用ofEntries()方法,需要在Map.Entry例項中包含每個map鍵值對。 JDK 9在Map介面中提供了一個方便的entry()靜態方法來建立Map.Entry的例項。 entry()方法的簽名如下:

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

為了保持表示式的可讀性和緊湊性,需要為Map.entry方法使用靜態匯入,並使用如下所示的語句來建立一個具有任意數量條目的不可修改的map:

import java.util.Map;
import static java.util.Map.entry;
// ...
// Use the Map.ofEntries() and Map.entry() methods to
// create an unmodifiable Map
Map<Integer, String> numberToWord =
          Map.ofEntries(entry(1, "One"),
                        entry(2, "Two"),
                        entry(3, "Three"));

Map介面的of()ofEntries()方法返回的map具有以下特徵:

  • 在結構上是不可變的。 嘗試新增,替換或刪除條目會丟擲UnsupportedOperationException異常。
  • 不允許在鍵或值中為null。 如果map中的鍵或值為null,則丟擲NullPointerException異常。
  • 如果所有鍵和值都是可序列化的,它們是可序列化的。
  • 不允許重複的鍵。 指定重複的鍵會引發IllegalArgumentException異常。
  • 對映的迭代順序是未指定的。
  • 對於返回的Map的實現類不能保證。 也就是說,不要指望返回的物件是HashMap或實現Map介面的任何其他類。 這些方法的實現是內部的,不應該假定他們的類名。 例如,Map.of()Map.of(1, "One")可能會返回兩個不同類的物件。

Collections類包含EMPTY_MAP的靜態欄位,表示不可變的空map。 它還包含一個emptyMap()的靜態方法來獲取不可變的空map。 singletonMap(K key, V value)方法返回具有指定鍵和值的不可變的單例map。 以下代段顯示了JDK 9和JDK 9之前建立不可變空map和單例map的方式:

// Creating an empty, immutable Map before JDK 9
Map<Integer,String> emptyMap1 = Collections.EMPTY_MAP;
Map<Integer,String> emptyMap2 = Collections.emptyMap();
// Creating an empty Map in JDK 9
Map<Integer,String> emptyMap = Map.of();
// Creating a singleton, immutable Map before JDK 9
Map<Integer,String> singletonMap1 =
    Collections.singletonMap(1, "One");
// Creating a singleton, immutable Map in JDK 9
Map<Integer,String> singletonMap = Map.of(1, "One");

下面包含一個完整的程式,顯示如何使用Map介面的of()ofEntries()entry() 靜態方法來建立不可變的
map。 請注意map中指定日期的順序以及輸出中顯示的順序。 它們可能不匹配,因為map更像set,不能保證其條目的檢索順序。

// MapTest.java
package com.jdojo.collection;
import java.util.Map;
import static java.util.Map.entry;
public class MapTest {
    public static void main(String[] args) {
        // Create few unmodifiable maps
        Map<Integer,String> emptyMap = Map.of();
        Map<Integer,String> luckyNumber = Map.of(19, "Nineteen");
        Map<Integer,String> numberToWord =
                Map.of(1, "One", 2, "Two", 3, "Three");
        Map<String,String> days = Map.ofEntries(
                entry("Mon", "Monday"),
                entry("Tue", "Tuesday"),
                entry("Wed", "Wednesday"),
                entry("Thu", "Thursday"),
                entry("Fri", "Friday"),
                entry("Sat", "Saturday"),
                entry("Sun", "Sunday"));
        System.out.println("emptyMap = " + emptyMap);
        System.out.println("singletonMap = " + luckyNumber);
        System.out.println("numberToWord = " + numberToWord);
        System.out.println("days = " + days);
        try {
            // Try using a null value
            Map<Integer,String> map = Map.of(1, null);
        } catch(NullPointerException e) {
            System.out.println("Nulls not allowed in Map.of().");
        }
        try {
            // Try using duplicate keys
            Map<Integer,String> map = Map.of(1, "One", 1, "On");
        } catch(IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
        try {
            // Try adding an entry
            luckyNumber.put(8, "Eight");
        } catch(UnsupportedOperationException e) {
            System.out.println("Cannot add an entry.");
        }
         try {
            // Try removing an entry
            luckyNumber.remove(0);
        } catch(UnsupportedOperationException e) {
            System.out.println("Cannot remove an entry.");
        }
    }
}

輸出結果為:

emptyMap = {}
singletonMap = {19=Nineteen}
numberToWord = {1=One, 3=Three, 2=Two}
days = {Sat=Saturday, Tue=Tuesday, Thu=Thursday, Sun=Sunday, Wed=Wednesday, Fri=Friday, Mon=Monday}
Nulls not allowed in Map.of().
duplicate key: 1
Cannot add an entry.
Cannot remove an entry.

五. 總結

在Java語言中支援collection literals是非常需要的功能。 JDK 9替代了對collection literals的支援,更新了Collection API,而是在ListSetMap介面中添加了of()靜態工廠方法,分別返回一個不可變的ListSetMap。該方法被過載,指定集合的​​零到十個元素。 ListSet介面提供了可變引數的of()方法,用於建立一個包含任意數量的元素的ListSetMap介面提供了ofEntries()靜態工廠方法,用於建立一個不可變的任意數量條目的MapMap介面還包含一個靜態的entry()方法,它接受一個鍵和一個值作為引數並返回一個Map.Entry例項。 ofEntries()entry()方法一起使用來建立任意數量條目的不可變的Map

這些介面中的新的靜態工廠方法為效能做了調整。 List.of()Set.of()方法不允許使用null元素。 Set.of()方法不允許重複的元素。 Map.of()Map.ofEntries()方法不允許重複鍵,或者將null作為鍵或值。