Java Collections.emptyMap 方法
上次修改时间:2025 年 4 月 20 日
Collections.emptyMap
方法返回一个不可变的空 Map。它是 Java Collections 实用程序类的一部分。此方法提供了一种类型安全的方式来获取一个空的 Map 实例。
返回的 Map 是可序列化的,并实现了 Map
接口。创建后它不能被修改。这使得它对于从方法返回空结果非常有用。
Collections.emptyMap 概述
Collections.emptyMap
在 Java 1.5 中引入。它返回一个单例的空 Map 实例。该方法是通用的,并返回一个具有指定类型参数的 Map<K,V>
。
主要优势是内存效率。由于它是不可变的和共享的,它不会创建新的实例。当需要频繁使用空 Map 时,这会减少内存使用。
基本 emptyMap 用法
此示例演示了 Collections.emptyMap
的最基本用法。我们获取一个空 Map 并验证其属性。该示例通过尝试修改 Map 来展示其不可变性。
package com.zetcode; import java.util.Collections; import java.util.Map; public class EmptyMapBasic { public static void main(String[] args) { // Get empty map Map<String, Integer> emptyMap = Collections.emptyMap(); // Verify properties System.out.println("Map size: " + emptyMap.size()); System.out.println("Is empty: " + emptyMap.isEmpty()); try { // Attempt to modify emptyMap.put("key", 1); } catch (UnsupportedOperationException e) { System.out.println("Expected exception: " + e.getMessage()); } } }
此代码展示了如何使用 Collections.emptyMap
获取一个空 Map。我们通过检查 size 和 isEmpty 来验证它是否为空。尝试修改它会抛出 UnsupportedOperationException
。
输出结果展示了 Map 的不可变性。这种行为与 Collections 类提供的所有不可变集合视图一致。
从方法返回空 Map
emptyMap
的一个常见用例是从方法返回空结果。此示例展示了一个根据条件返回已填充的 Map 或空 Map 的方法。
package com.zetcode; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class EmptyMapReturn { public static Map<String, Integer> getWordCounts(String text) { if (text == null || text.trim().isEmpty()) { return Collections.emptyMap(); } Map<String, Integer> counts = new HashMap<>(); String[] words = text.split("\\s+"); for (String word : words) { counts.merge(word, 1, Integer::sum); } return counts; } public static void main(String[] args) { System.out.println("Non-empty text: " + getWordCounts("hello world hello")); System.out.println("Empty text: " + getWordCounts("")); } }
此示例演示了将 emptyMap
用作返回值。getWordCounts
方法对于空输入返回一个空 Map。对于非空输入,它返回一个带有单词计数的已填充 Map。
在这里使用 emptyMap
比创建新的 HashMap 实例更有效。它还清楚地向调用代码发出了空结果信号。
类型安全的空 Map
Collections.emptyMap
通过泛型提供类型安全。此示例展示了如何将其与不同的类型参数一起使用。编译器在编译时强制执行类型安全。
package com.zetcode; import java.util.Collections; import java.util.Map; public class EmptyMapTypes { public static void main(String[] args) { // String-Integer map Map<String, Integer> stringIntMap = Collections.emptyMap(); System.out.println("String-Integer map: " + stringIntMap); // Integer-String map Map<Integer, String> intStringMap = Collections.emptyMap(); System.out.println("Integer-String map: " + intStringMap); // Nested maps Map<String, Map<String, Integer>> nestedMap = Collections.emptyMap(); System.out.println("Nested map: " + nestedMap); // The following would cause compile-time error: // stringIntMap.put(1, "one"); // Incompatible types } }
此示例展示了具有不同泛型类型参数的 emptyMap
。我们演示了简单的 Map、嵌套 Map,以及编译器如何防止类型不匹配。类型安全有助于及早发现错误。
输出结果表明,无论类型参数如何,这些 Map 都是空的。类型参数只影响编译时检查,而不影响运行时行为。
空 Map 作为默认值
空 Map 可以用作 Map 字段或参数的默认值。此示例展示了使用 emptyMap
来初始化一个字段并提供默认参数值。
package com.zetcode; import java.util.Collections; import java.util.Map; public class EmptyMapDefault { private Map<String, String> configurations = Collections.emptyMap(); public void printConfigurations( Map<String, String> overrideConfigs) { Map<String, String> effectiveConfigs = overrideConfigs.isEmpty() ? configurations : overrideConfigs; System.out.println("Current configurations:"); effectiveConfigs.forEach((k, v) -> System.out.println(k + " = " + v)); } public static void main(String[] args) { EmptyMapDefault demo = new EmptyMapDefault(); // Use default empty map demo.printConfigurations(Collections.emptyMap()); // Use provided map demo.printConfigurations( Map.of("timeout", "100", "retries", "3")); } }
此示例演示了将 emptyMap
用作默认值。类字段使用一个空 Map 进行初始化。该方法使用默认的或提供的配置 Map。
输出结果展示了两种情况:使用默认的空 Map 和使用提供的 Map。这种模式在配置处理和类似场景中很常见。
Collections 框架中的空 Map
空 Map 与其他 Collections 框架功能集成。此示例展示了如何将其与诸如 putAll
和流操作之类的方法一起使用。
package com.zetcode; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class EmptyMapFramework { public static void main(String[] args) { // Using with putAll Map<String, Integer> map1 = new HashMap<>(); map1.putAll(Collections.emptyMap()); System.out.println("After putAll: " + map1); // Using with streams Map<String, Integer> result = Collections.emptyMap() .entrySet() .stream() .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue)); System.out.println("Stream result: " + result); // Using with Map.copyOf (Java 10+) Map<String, Integer> copiedMap = Map.copyOf(Collections.emptyMap()); System.out.println("Copied map: " + copiedMap); } }
此示例展示了 emptyMap
与其他 Collections 框架功能的配合使用。我们演示了 putAll
、流和 Map.copyOf
。空 Map 在所有情况下都表现正确。
输出结果表明,使用空 Map 的操作会产生空或未更改的结果。这使得空 Map 可以安全地用于各种集合操作。
性能注意事项
使用 Collections.emptyMap
具有性能优势。此示例将其与创建新的 HashMap 实例进行了比较。我们测量了内存使用量和执行时间。
package com.zetcode; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class EmptyMapPerformance { public static void main(String[] args) { final int ITERATIONS = 1_000_000; // Test emptyMap long start = System.nanoTime(); for (int i = 0; i < ITERATIONS; i++) { Map<String, String> m = Collections.emptyMap(); } long emptyMapTime = System.nanoTime() - start; // Test new HashMap start = System.nanoTime(); for (int i = 0; i < ITERATIONS; i++) { Map<String, String> m = new HashMap<>(); } long hashMapTime = System.nanoTime() - start; System.out.println("Collections.emptyMap time: " + emptyMapTime / 1_000_000 + " ms"); System.out.println("new HashMap time: " + hashMapTime / 1_000_000 + " ms"); System.out.println("Ratio: " + (double)hashMapTime / emptyMapTime); } }
此示例比较了 emptyMap
与创建新的 HashMap 实例的性能。测试创建了每种类型的 Map 一百万次,并测量了经过的时间。
输出结果表明 emptyMap
明显更快。这是因为它重用了单个不可变实例,而不是创建新对象。
空 Map 序列化
Collections.emptyMap
返回的空 Map 是可序列化的。此示例演示了序列化和反序列化一个空 Map。我们使用 Java 的标准序列化机制。
package com.zetcode; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Collections; import java.util.Map; public class EmptyMapSerialization { public static void main(String[] args) throws IOException, ClassNotFoundException { Map<String, Integer> originalMap = Collections.emptyMap(); // Serialize ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(originalMap); oos.close(); // Deserialize ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); @SuppressWarnings("unchecked") Map<String, Integer> deserializedMap = (Map<String, Integer>) ois.readObject(); System.out.println("Original map: " + originalMap); System.out.println("Deserialized map: " + deserializedMap); System.out.println("Same instance: " + (originalMap == deserializedMap)); } }
此示例展示了空 Map 可以被序列化和反序列化。该过程保留了 Map 的空状态。反序列化后,我们仍然有一个可用的空 Map。
输出结果确认了序列化工作正常。请注意,反序列化的 Map 可能不是完全相同的单例实例,但行为将完全相同。
来源
在本文中,我们深入探讨了 Java 的 Collections.emptyMap
方法。我们涵盖了基本用法、类型安全、性能以及与其他集合功能的集成。空 Map 是许多场景中一个有用的工具。
作者
列出所有Java教程。