Java中如何实现不可变Map详解
前言
有时最好不允许修改 java.util.Map,例如跨线程共享只读数据。为此,我们可以使用UnmodifiableMap或ImmutableMap。
在这个快速教程中,我们将看到它们之间的区别。然后,我们将介绍可以创建不可变Map的各种方法。
下面话不多说了,来一起看看详细的介绍吧
不可修改与不可变
UnmodifiableMap其实是一个可以修改的map的包装器,不允许直接修改它。
MapmutableMap=newHashMap<>(); mutableMap.put("USA","NorthAmerica"); Map unmodifiableMap=Collections.unmodifiableMap(mutableMap); assertThrows(UnsupportedOperationException.class, ()->unmodifiableMap.put("Canada","NorthAmerica"));
但是包装器里面底层的可变Map仍然可以改变,修改也反映在不可修改的Map中:
mutableMap.remove("USA"); assertFalse(unmodifiableMap.containsKey("USA")); mutableMap.put("Mexico","NorthAmerica"); assertTrue(unmodifiableMap.containsKey("Mexico"));
另一方面,不可变Map包含其自己的私有数据,是不允许对其进行修改。因此,一旦创建了不可变Map的实例,数据就不会以任何方式改变。
Guava不变Map
Guava提供了每个java.util的不可变版本。使用 ImmutableMap映射。每当我们尝试修改它时,它都会抛出 UnsupportedOperationException。
由于它包含自己的私有数据,因此在更改原始地图时,此数据不会更改。
我们现在将讨论创建ImmutableMap实例的各种方法 。
1.使用copyOf()方法:
首先,让我们使用ImmutableMap.copyOf() 方法,该方法返回原始Map中所有条目的副本:
ImmutableMapimmutableMap=ImmutableMap.copyOf(mutableMap); assertTrue(immutableMap.containsKey("USA"));
它不能直接修改,但是可以改变其内部可变的Map:
assertThrows(UnsupportedOperationException.class, ()->immutableMap.put("Canada","NorthAmerica")); mutableMap.remove("USA"); assertTrue(immutableMap.containsKey("USA")); mutableMap.put("Mexico","NorthAmerica"); assertFalse(immutableMap.containsKey("Mexico"));
2.使用builder()方法
我们还可以使用 ImmutableMap.builder() 方法创建原始Map中所有条目的副本。
此外,我们可以使用此方法添加原始Map中不存在的其他条目:
ImmutableMapimmutableMap=ImmutableMap. builder() .putAll(mutableMap) .put("CostaRica","NorthAmerica") .build(); assertTrue(immutableMap.containsKey("USA")); assertTrue(immutableMap.containsKey("CostaRica"));
3.使用of()
最后,我们可以使用ImmutableMap.of() 方法创建一个不可变的Map,其中包含动态提供的一组条目。它最多支持五个键/值对:
ImmutableMapimmutableMap =ImmutableMap.of("USA","NorthAmerica","CostaRica","NorthAmerica"); assertTrue(immutableMap.containsKey("USA")); assertTrue(immutableMap.containsKey("CostaRica"));
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。