如何在Java11中设置HashMapFinal的键值对?
问题1:如何在Java11中设置HashMapFinal的键值对?,java,hashmap,final,java-11,Java,Hashmap,Final,Java 11,问题1: 如果我将exits声明为private final Map exits,它为什么不起作用? 问题2: 还有其他方法可以达到同样的效果吗? P:我是java新手,所以如果我可能会混淆C++概念和java java,那么请纠正我。 < P>答案1: map < /Cord>不是Java中的有效语法。我不知道你这是什么意思。这个用法使我想起C++中的代码> const < /Cord>修饰符,但最终不是const,无论如何,字符串和整数都是不可变的 回答2:您的getExits方法返回地图的
如果我将
exits
声明为private final Map exits,它为什么不起作用代码>?
问题2:
还有其他方法可以达到同样的效果吗?
P:我是java新手,所以如果我可能会混淆C++概念和java java,那么请纠正我。 < P>答案1:<代码> map < /Cord>不是Java中的有效语法。我不知道你这是什么意思。这个用法使我想起C++中的代码> const < /Cord>修饰符,但最终不是const,无论如何,字符串和整数都是不可变的
回答2:您的getExits
方法返回地图的可修改副本。这是可行的,但更常见的是返回数据结构的不可修改视图。它是一个轻量级修饰符,如果调用方试图进行更改,但调用原始映射中的方法,则会引发异常。如果调用方需要映射,则必须复制映射本身
import java.util.HashMap;
import java.util.Map;
public class Foo {
private final Map<String, Integer> exits;
public Foo(Map<String, Integer> exits) {
this.exits = exits;
}
public Map<String, Integer> getExits() {
return new HashMap<>(exits);
}
public void show() {
for (String i : exits.keySet()) {
System.out.println(i + ": " + exits.get(i));
}
}
}
class Bar {
public static void main(String[] args) {
Map<String, Integer> temp=new HashMap<>();
temp.put("A", 1);
temp.put("B", 2);
Foo foo = new Foo(temp);
foo.show();
//Okay, no problem.
//Output: A: 1
// B: 2
foo.getExits().replace("A", 10);
foo.getExits().remove("B");
foo.show();
//Output: A: 1
// B: 2
}
}
publicmap getExits(){
返回集合。不可修改映射(退出);
}
第一个问题:
实际上,在第二段代码中,当您每次调用getexits时,它都会返回一个不同的浅层副本(新Hashmap)。浅层副本是出口的不同副本,您只能修改返回的映射,而不能修改在foo类中声明的原始映射。因此,foo.getexits()是您返回的完全不同的映射,它每次都在修改新的hashmap,而不是临时映射或foo(temp)。如果您这样编码
public Map<String, Integer> getExits() {
return Collections.unmodifiableMap(exits);
}
而不是
temp.replace("A",10);
temp.remove("B");
foo.show();
然后它将打印与第一个程序相同的输出。(它还将修改)。
很快,您的第二个代码不会被修改,因为每次您返回和修改一个与temp无关的新hashmap时,这些都不会影响您的foo(temp)
第二个问题:
如果确实不想修改main类中的任何内容,则可以在第二个程序的getexits()方法中编写如下代码:
foo.getExits().replace("A", 10);
foo.getExits().remove("B");
foo.show();
不要像你那样改变第二个程序的任何内容,它会抛出
return Collections.unmodifiableMap(exits);
每当你想用foo.getexits()修改并阻止你修改它时。但是你仍然可以单独修改temp,因为它与getexits方法没有关系。我和你一样也是初学者,但我试着用我的小知识回答你的问题。希望,这会有帮助你想要集合.unmodifiableMap()
或者像Guava的ImmutableMap
@chrylis onstrike这样的不可变版本-你能更详细地向我解释一下吗?阅读关于集合.unmodifiableMap.Final的内容。Final只会使引用成为Final,所以你不能将它指向新的地图。它与使数据不可变的c的常量不同。通过创建一个类不公开的重复映射,您可能能够实现您所追求的目标。当调用getExits时,返回一个不可修改的映射(它只是现有映射的一个视图)。编辑:如您的额外示例。或Java12的Map.copyOf()
。
return Collections.unmodifiableMap(exits);
java.lang.UnsupportedOperationException