Java的不可变映射表(Immutable Map)

Java的不可变映射表(Immutable Map)

  • ImmutableMap,从名称上就可以看出,是一种不可变类型的映射表(Map)。这意味着映射表的内容在声明后就已经固定或常量了,也就是说,它们是“只读”的。
  • 如果尝试在映射表中添加、删除和更新元素,则会抛出“UnsupportedOperationException”异常。
  • ImmutableMap 也不允许有空元素。
  • 如果尝试创建一个有空元素的 ImmutableMap,则会抛出“NullPointerException”异常。如果试图在 Map 中添加空元素,则会抛出“UnsupportedOperationException”异常。

ImmutableMap的优点

  • 它们是“线程安全”的。
  • 它们是“内存高效”的。
  • 由于它们是不可变的,因此可以轻松地传递给第三方库,无需担心数据会被修改。

注意 它是一个不可变集合,而不是一组不可变对象,因此其中的对象可以被修改。

类声明:

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

类层次结构:

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

创建不可变映射表 不可变映射表可通过各种方法创建。例如:

通过Guava的copyOf()函数从现有Map中创建

// 下面是一个Java示例程序,用于创建ImmutableMap
 
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
 
class MapUtil {
 
    // 从Map创建ImmutableMap的函数
    public static <K, T> void iMap(Map<K, T> map)
    {
        // 使用copyOf()从Map中创建ImmutableMap
        ImmutableMap<K, T> immutableMap = ImmutableMap.copyOf(map);
 
        // 打印ImmutableMap
        System.out.println(immutableMap);
    }
 
    public static void main(String[] args)
    {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "Geeks");
        map.put(2, "For");
        map.put(3, "Geeks");
        iMap(map);
    }
}

输出:

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

通过Guava的of()函数创建新的ImmutableMap

// 下面是一个Java程序,用于创建ImmutableMap
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
 
class MapUtil {
 
    // 创建ImmutableMap的函数
    public static void createImmutableMap()
    {
        // 使用of()创建ImmutableMap
        ImmutableMap<Integer, String> immutableMap = ImmutableMap.of(
            1, "Geeks",
            2, "For",
            3, "Geeks");
 
        // 打印ImmutableMap
        System.out.println(immutableMap);
    }
 
    public static void main(String[] args)
    {
        createImmutableMap();
    }
}

使用Java 9的of()方法创建 在Java中,可以使用Set、Map或List和of()方法来创建不可变映射表。 请注意:下面的程序是Java 9的,因此需要Java 9编译器才能运行它们。

// Java代码示例说明了如何使用of()方法创建一个ImmutableSet
// 导入需要的包
import java.util.*;
import com.google.common.collect.ImmutableMap;
 
class GfG {
    public static void main(String args[])
    {
        // 创建一个非空的immutable集合
        Map<Integer, String> map = Map.of(
            1, "Geeks",
            2, "For",
            3, "Geeks");
 
        // 输出immutable集合
        System.out.println(map);
    }
}

输出:

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

使用ImmutableMap中的Builder() 在Guava中,ImmutableMap提供了一个Builder()函数,可通过此函数创建一个新的ImmutableMap,或从现有的Map创建一个ImmutableMap,或两者一起使用。

  • 创建一个新的ImmutableMap
// Java代码示例说明了如何使用of()方法创建一个ImmutableSet
// 导入需要的包
import java.util.*;
import com.google.common.collect.ImmutableMap;
 
class GfG {
    public static void main(String args[])
    {
        // 创建一个非空的immutable集合
        ImmutableMap<Integer, String> imap =
                         ImmutableMap.<Integer, String>builder()
                                                 .put(1, "Geeks")
                                                 .put(2, "For")
                                                 .put(3, "Geeks")
                                                 .build();
 
        // 输出immutable集合
        System.out.println(imap);
    }
}

输出:

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

从现有的Map中创建一个ImmutableMap

// Java代码示例说明了如何使用of()方法创建一个ImmutableSet
// 导入需要的包
import java.util.*;
import com.google.common.collect.ImmutableMap;
 
class GfG {
    public static void main(String args[])
    {
        // 创建一个非空的immutable集合
        Map<Integer, String> map = Map.of(1, "Geeks",
                                          2, "For",
                                          3, "Geeks");
        ImmutableMap<Integer, String> imap =
                       ImmutableMap.<Integer, String>builder()
                                                 .putAll(map)
                                                 .build();
 
        // 输出immutable集合
        System.out.println(imap);
    }
}

输出:

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

创建一个包含现有Map的新ImmutableMap

// Java代码示例说明了如何使用of()方法创建一个ImmutableSet
// 导入需要的包
import java.util.*;
import com.google.common.collect.ImmutableMap;
 
class GfG {
    public static void main(String args[])
    {
        // 创建一个非空的immutable集合
        Map<Integer, String> map = Map.of(1, "Geeks",
                                          2, "For",
                                          3, "Geeks");
        ImmutableMap<Integer, String> imap =
                     ImmutableMap.<Integer, String>builder()
                                               .putAll(map)
                                         .put(4, "Computer")
                                           .put(5, "Portal")
                                                   .build();
 
        // 输出immutable集合
        System.out.println(imap);
    }
}

输出:

{1=Geeks, 2=For, 3=Geeks, 4=Computer, 5=Portal}
{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<Integer, String> 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,以使包装器不能用于修改它。然而,我们仍然可以改变原始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<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "Geeks");
        map.put(2, "For");
        map.put(3, "Geeks");
 
        // Create ImmutableMap from Map using copyOf()
        Map<Integer, String> 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<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "Geeks");
        map.put(2, "For");
        map.put(3, "Geeks");
 
        // Create ImmutableMap from Map using copyOf()
        ImmutableMap<Integer, String> 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}

另一种方法:

1) 使用Collections.singletonMap()

描述: Collections.singletonMap()方法返回一个不可变映射,它只包含一个映射。它用于创建仅具有单个键值对的映射。

语法:

Collections.singletonMap(key, value)

例子:

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
 
public class SingletonMapDemo {
    public static void main(String[] args)
    {
        // 创建一个单例映射,仅有一个键值对
 
        Map<String, Integer> map
            = Collections.singletonMap("gfg", 25);
 
        // 向映射添加一个新的键值对
 
        // 输出映射
        System.out.println(map);
    }
}

输出

{gfg=25}
注意:这会抛出 UnsupportedOperationException,因为映射是不可变的

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程