从这个链接
名称对象是不可变的。在所有其他条件相同的情况下,不可变类型是可行的方法,特别是对于将用作 Sets 中的元素或 Maps 中的键的对象。如果您在集合中修改它们的元素或键,这些集合将中断。我们怎么知道“Name”类是不可变的?(在上面提到的链接中可见类名)
“如果你修改它们的元素,这些集合就会破坏”,它们实际上是什么意思?
提前致谢。
从这个链接
名称对象是不可变的。在所有其他条件相同的情况下,不可变类型是可行的方法,特别是对于将用作 Sets 中的元素或 Maps 中的键的对象。如果您在集合中修改它们的元素或键,这些集合将中断。我们怎么知道“Name”类是不可变的?(在上面提到的链接中可见类名)
“如果你修改它们的元素,这些集合就会破坏”,它们实际上是什么意思?
提前致谢。
因为使用可变类,您可以更改它们在集合中组织/排序的属性,而持有者类不会知道它。
认为你可以这样做:
public class Name implements Comparable<Name> {
private String firstname = null
// getters and setters
public int compareTo(Name name) {
// Compare based in firstName
}
}
进而:
Name name1 = new Name("John");
Name name2 = new Name("Mike");
SortedSet<Name> set = new TreeSet<Name>();
set.add(name1);
set.add(name2);
name1.setFirstName("Ralph");
现在,是否已set
订购?
以类似的方式,影响hashCode
实例中断HashMap
和类似情况的更改,因为在插入/检索对象时执行这些类的第一个是使用bucket
基于该值的特定。
他们的意思是,基于对象的查找将失败。
例如:
mylist.get(myObject);
将失败,因为您拥有的对象引用将与您用来get(...)
调用的对象引用不同(由于修改)。
HashSet
并HashMap
依赖于 .javadoc 中的合同equals()
和hashCode
描述java.lang.Object
。这意味着对于equals()
根据计算结果相等的两个对象hashCode()
也必须相等。
如果hashCode()
for 中的对象在Set
orMap
期间发生更改,则Set
执行Map
将找不到对象,因为它保存在 old 的存储桶中hashCode()
。
因此,更改hashCode()
对象在Set
或中的Map
时间是一个非常糟糕的主意。
从文档开始Map
注意:如果将可变对象用作映射键,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是映射中的键,则不指定映射的行为。此禁令的一个特殊情况是不允许映射包含自己作为键。虽然允许映射将自身包含为一个值,但建议格外小心:equals 和 hashCode 方法不再在此类映射上得到很好的定义。
从码头开始Set
注意:如果将可变对象用作集合元素,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是集合中的一个元素,则不指定集合的行为。此禁令的一个特殊情况是不允许集合包含自身作为元素。
查找是.equals
在键上完成的,如果键是可变的,则查找将失败。