1

从这个链接

名称对象是不可变的。在所有其他条件相同的情况下,不可变类型是可行的方法,特别是对于将用作 Sets 中的元素或 Maps 中的键的对象。如果您在集合中修改它们的元素或键,这些集合将中断。我们怎么知道“Name”类是不可变的?(在上面提到的链接中可见类名)

“如果你修改它们的元素,这些集合就会破坏”,它们实际上是什么意思?

提前致谢。

4

4 回答 4

5

因为使用可变类,您可以更改它们在集合中组织/排序的属性,而持有者类不会知道它。

认为你可以这样做:

 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基于该值的特定。

于 2013-06-24T13:35:27.253 回答
1

他们的意思是,基于对象的查找将失败。

例如:

mylist.get(myObject);

将失败,因为您拥有的对象引用将与您用来get(...)调用的对象引用不同(由于修改)。

于 2013-06-24T13:33:15.127 回答
1

HashSetHashMap依赖于 .javadoc 中的合同equals()hashCode描述java.lang.Object。这意味着对于equals()根据计算结果相等的两个对象hashCode()也必须相等。

如果hashCode()for 中的对象在SetorMap期间发生更改,则Set执行Map将找不到对象,因为它保存在 old 的存储桶中hashCode()

因此,更改hashCode()对象在Set或中的Map时间是一个非常糟糕的主意。

于 2013-06-24T13:38:52.453 回答
0

从文档开始Map

注意:如果将可变对象用作映射键,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是映射中的键,则不指定映射的行为。此禁令的一个特殊情况是不允许映射包含自己作为键。虽然允许映射将自身包含为一个值,但建议格外小心:equals 和 hashCode 方法不再在此类映射上得到很好的定义。

从码头开始Set

注意:如果将可变对象用作集合元素,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是集合中的一个元素,则不指定集合的​​行为。此禁令的一个特殊情况是不允许集合包含自身作为元素。

查找是.equals在键上完成的,如果键是可变的,则查找将失败。

于 2013-06-24T13:34:46.163 回答