【发布时间】:2020-04-11 19:43:35
【问题描述】:
import java.util.HashMap;
import java.util.Map;
public class Foo {
private final Map<String, Integer> exits;
public Foo() {
this.exits = new HashMap<>();
}
public Map<String, Integer> getExits() {
return exits;
}
public void show() {
for (String i : exits.keySet()) {
System.out.println(i + ": " + exits.get(i));
}
}
}
class Bar {
public static void main(String[] args) {
Foo foo = new Foo();
foo.getExits().put("A", 1);
foo.getExits().put("B", 2);
foo.show();
//Okay, no problem.
//Output: A: 1
// B: 2
foo.getExits().replace("A", 10);
foo.getExits().remove("B");
foo.show();
//Output: A: 10
}
}
我已经在Foo 类中将exits 声明为final,这样一旦在构造函数中分配了它就不能引用另一个HashMap。我还想将exits 中的每个元素都设置为final,这样一旦我在exits 中放置了一个键值对,就不能以任何方式修改或删除它。我尝试了以下方法(注意getExits()方法和main()方法的变化):
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
}
}
问题 1:
如果我将exits 声明为private final Map<final String, final Integer> exits;,为什么它不起作用?
问题2:
有没有其他方法可以达到同样的效果?
P.S:我是Java新手,如果有任何错误请纠正我,因为我可能将C++概念与Java混合在一起。
【问题讨论】:
-
你想要
Collections.unmodifiableMap()或者像 Guava 的ImmutableMap这样的不可变版本。 -
@chrylis-onstrike- 你能详细解释一下吗?
-
了解 Collections.unmodifiableMap here。
-
Final 只是使参考成为最终的,因此您不能将其指向新地图。它与使数据不可变的 c 的 const 不同。您可以通过创建您的类不公开的重复 Map 来实现您所追求的目标。例如。当您调用 getExits 时,您会返回一个 unmodifiableMap (这只是您现有地图的视图)。编辑:就像你的额外例子一样。
-
或 Java 12 的
Map.copyOf()。
标签: java hashmap final java-11