Java 内容不为';不变

Java 内容不为';不变,java,collections,map,immutability,Java,Collections,Map,Immutability,我希望地图提供其值和视图的副本,这样条目就不会以任何方式被意外修改。是否有这样的实施?我已经查看了Guava的实例,但还没有找到我想要的。没有直接的方法,一旦通过获取元素,地图就会按值存储对对象的引用 Value v = map.get(key) 贴图无法禁止修改对象 有两种选择,您可以为每次调用返回对象的副本,根据您从映射中获取数据的频率,这可能是低效的,例如: public class MyMap<K,V> extends HashMap<K,V> { @Ove

我希望地图提供其值和视图的副本,这样条目就不会以任何方式被意外修改。是否有这样的实施?我已经查看了Guava的实例,但还没有找到我想要的。

没有直接的方法,一旦通过获取元素,地图就会按值存储对对象的引用

Value v = map.get(key)
贴图无法禁止修改对象

有两种选择,您可以为每次调用返回对象的副本,根据您从映射中获取数据的频率,这可能是低效的,例如:

public class MyMap<K,V> extends HashMap<K,V> {
  @Override
  public V get(K key) {
    V v = super.get(key);
    return v != null ? v.clone() : null;
  }

但是,如果您不对每个包含的成员变量递归地应用相同的方法,这将允许修改
字段1
内容。

要拥有不可修改的映射,可以使用Collection.unmodifiableMap函数。 如果您想要一个不可变的映射,那么您也必须映射映射的键和值。这可以通过使用定义了not setter的接口来实现,也可以通过将键和值复制到不允许修改数据的实现来实现


在我看来,最好是分发副本,这样对地图副本的更改不会更改原始地图。这种技术被称为防御性复制。

你打算在地图上放置什么样的物体?最好使用Guava的ImmutableMap()和不可变的键和值

阅读Joshua Bloch(第二版)中的第15项“最小化可变性”,了解背景信息。Bloch提供了关于实现不可变类的实用建议,并解释了为什么不可变性是一个好主意:“不可变类比可变类更易于设计、实现和使用。它们不太容易出错,也更安全。”


如果将可变对象放在(不可变)映射中,映射的用户仍然可以更改这些对象(即使映射保持不变),而您实际上对此无能为力()。

您无法获得键或值的自动副本,只能获得保存它的结构的自动副本。这就是你想要的吗?@Leo:immutability指的是映射本身,而不是包含的元素。我认为在Java中,你不能这样做,除非你以某种方式克隆条目,或者只允许不可变类,例如
Java.lang.String
Java.lang.Integer
等等。
class Value {
  public final Field1 field1;
  public final Field2 field2;

  public Value(Field1 field1, Field2 field2) {
    this.field1 = field1;
    this.field2 = field2;
  }
}