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,因为映射是不可变的
极客教程