📜  Java中的不可变映射

📅  最后修改于: 2022-05-13 01:55:46.476000             🧑  作者: Mango

Java中的不可变映射

  • ImmutableMap,顾名思义,是一种不可变的 Map。表示声明后map的内容是固定的或不变的,即只读
  • 如果尝试在 Map 中添加、删除和更新元素,则会引发UnsupportedOperationException
  • ImmutableMap 也不允许空元素。
  • 如果尝试使用 null 元素创建 ImmutableMap,则会引发NullPointerException 。如果尝试在 Map 中添加 null 元素,则会引发UnsupportedOperationException

ImmutableMap 的优点

  • 它们是线程安全的。
  • 它们具有内存效率。
  • 由于它们是不可变的,因此它们可以毫无问题地传递给第三方库

注意它是不可变集合,不是不可变对象的集合,所以里面的对象是可以修改的。
类声明:

@GwtCompatible(serializable=true,
               emulated=true)
public abstract class ImmutableMap
extends Object
implements Map, Serializable

类层次结构:

java.lang.Object
  ↳ com.google.common.collect.ImmutableMap 

创建不可变映射
ImmutableMap 可以通过各种方法创建。这些包括:

  1. 使用 Guava 的 copyOf()函数从现有 Map
    // Below is the Java program to create ImmutableMap
      
    import com.google.common.collect.ImmutableMap;
    import java.util.HashMap;
    import java.util.Map;
      
    class MapUtil {
      
        // Function to create ImmutableMap from Map
        public static  void iMap(Map map)
        {
            // Create ImmutableMap from Map using copyOf()
            ImmutableMap immutableMap = ImmutableMap.copyOf(map);
      
            // Print the ImmutableMap
            System.out.println(immutableMap);
        }
      
        public static void main(String[] args)
        {
            Map map = new HashMap();
            map.put(1, "Geeks");
            map.put(2, "For");
            map.put(3, "Geeks");
            iMap(map);
        }
    }
    

    输出:

    {1=Geeks, 2=For, 3=Geeks}
    
  2. 使用来自 Guava 的 of()函数的新 ImmutableMap
    // Below is the Java program to create ImmutableMap
    import com.google.common.collect.ImmutableMap;
    import java.util.HashMap;
    import java.util.Map;
      
    class MapUtil {
      
        // Function to create ImmutableMap
        public static void createImmutableMap()
        {
            // Create ImmutableMap using of()
            ImmutableMap immutableMap = ImmutableMap.of(
                1, "Geeks",
                2, "For",
                3, "Geeks");
      
            // Print the ImmutableMap
            System.out.println(immutableMap);
        }
      
        public static void main(String[] args)
        {
            createImmutableMap();
        }
    }
    

    输出:

    {1=Geeks, 2=For, 3=Geeks}
    
  3. 使用Java 9 Factory Of() 方法

    在Java中,将 of() 与 Set、Map 或 List 一起使用来创建不可变映射。

    请注意:以下程序是Java 9 的。因此您需要Java 9 编译器来运行它们。

    // Java code illustrating of() method to
    // create a ImmutableSet
    import java.util.*;
    import com.google.common.collect.ImmutableMap;
      
    class GfG {
        public static void main(String args[])
        {
            // non-empty immutable set
            Map map = Map.of(
                1, "Geeks",
                2, "For",
                3, "Geeks");
      
            // Let's print the set
            System.out.println(map);
        }
    }
    

    输出:

    {1=Geeks, 2=For, 3=Geeks}
    
  4. 使用 ImmutableMap 中的 Builder()

    在 Guava 中,ImmnutableMap 类提供了一个函数Builder()。通过这个函数,可以创建一个新的 ImmutableMap,或者
    ImmutableMap 可以从现有的 Map 或两者中创建。

    • 创建一个新的 ImmutableMap
      // Java code illustrating of() method to
      // create a ImmutableSet
      import java.util.*;
      import com.google.common.collect.ImmutableMap;
        
      class GfG {
          public static void main(String args[])
          {
              // non-empty immutable set
              ImmutableMap imap = 
                               ImmutableMap.builder()
                                                       .put(1, "Geeks")
                                                       .put(2, "For")
                                                       .put(3, "Geeks")
                                                       .build();
        
              // Let's print the set
              System.out.println(imap);
          }
      }
      

      输出:

      {1=Geeks, 2=For, 3=Geeks}
      
    • 从现有 Map 创建 ImmutableMap
      // Java code illustrating of() method to
      // create a ImmutableSet
      import java.util.*;
      import com.google.common.collect.ImmutableMap;
        
      class GfG {
          public static void main(String args[])
          {
              // non-empty immutable set
              Map map = Map.of(1, "Geeks",
                                                2, "For",
                                                3, "Geeks");
              ImmutableMap imap = 
                             ImmutableMap.builder()
                                                       .putAll(map)
                                                       .build();
        
              // Let's print the set
              System.out.println(imap);
          }
      }
      

      输出:

      {1=Geeks, 2=For, 3=Geeks}
      
    • 创建一个包含现有 Map 的新 ImmutableMap
      // Java code illustrating of() method to
      // create a ImmutableSet
      import java.util.*;
      import com.google.common.collect.ImmutableMap;
        
      class GfG {
          public static void main(String args[])
          {
              // non-empty immutable set
              Map map = Map.of(1, "Geeks",
                                                2, "For",
                                                3, "Geeks");
              ImmutableMap imap = 
                           ImmutableMap.builder()
                                                     .putAll(map)
                                               .put(4, "Computer")
                                                 .put(5, "Portal")
                                                         .build();
        
              // Let's print the set
              System.out.println(imap);
          }
      }
      

      输出:

      {1=Geeks, 2=For, 3=Geeks, 4=Computer, 5=Portal}
      


尝试改变 ImmutableMap

如前所述,以下程序将抛出UnsupportedOperationException

// Java code to show that UnsupportedOperationException
// will be thrown when ImmutableMap is modified.
import java.util.*;
  
class GfG {
    public static void main(String args[])
    {
        // empty immutable map
        Map map = Map.of();
  
        // Lets try adding element in these set
        map.put(1, "Geeks");
        map.put(2, "For");
        map.put(3, "Geeks");
    }
}

输出 :

Exception in thread "main" java.lang.UnsupportedOperationException
    at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:218)
    at ImmutableListDemo.main(Main.java:16)

它与 Collections.unmodifiableMap() 有何不同?

Collections.unmodifiableMap 围绕同一个现有 Map 创建一个包装器,这样包装器就不能用于修改它。但是我们仍然可以更改原始地图。

// Java program to demonstrate that a Map created using
// Collections.unmodifiableMap() can be modified indirectly.
import java.io.*;
import java.util.*;
  
class GFG {
    public static void main(String[] args)
    {
        Map map = new HashMap();
        map.put(1, "Geeks");
        map.put(2, "For");
        map.put(3, "Geeks");
  
        // Create ImmutableMap from Map using copyOf()
        Map imap = Collections.unmodifiableMap(map);
  
        // We change map and the changes reflect in imap.
        map.put(4, "Computer");
        map.put(5, "Portal");
  
        System.out.println(imap);
    }
}

输出:

{1=Geeks, 2=For, 3=Geeks, 4=Computer, 5=Portal}

如果我们从现有 Map 创建 ImmutableMap 并更改现有 Map,则 ImmutableMap 不会更改,因为创建了副本。

// Below is a Java program for
// Creating an immutable Map using copyOf()
// and modifying original Map.
import java.io.*;
import java.util.*;
import com.google.common.collect.ImmutableMap;
  
class GFG {
    public static void main(String[] args)
    {
        Map map = new HashMap();
        map.put(1, "Geeks");
        map.put(2, "For");
        map.put(3, "Geeks");
  
        // Create ImmutableMap from Map using copyOf()
        ImmutableMap imap = ImmutableMap.copyOf(map);
  
        // We change map and the changes wont reflect in imap.
        map.put(4, "Computer");
        map.put(5, "Portal");
  
        System.out.println(imap);
    }
}

输出 :

{1=Geeks, 2=For, 3=Geeks}