我有这个代码:
public class Tray {
private Set<Block> blocks;
private int numColumns;
private int numRows;
//constructor
public Tray (int numRows, int numColumns){
this.numColumns = numColumns;
this.numRows = numRows;
blocks = new HashSet<>();
}
public boolean satisfiesGoal(Tray other){
Block thisBlock = this.blocks.iterator().next();
Block otherBlock = other.blocks.iterator().next();
boolean hashesEqual = thisBlock.hashCode() == otherBlock.hashCode(); // this is true
boolean areEqual = thisBlock.equals(otherBlock) && otherBlock.equals(thisBlock); // this is true
boolean contains = this.blocks.contains(otherBlock); // this is false, why?
return contains;
}
在主要方法中,我已将 2 个块添加到各自的托盘中。根据调试器,变量“hashesEqual”和“areEqual”为 true,但布尔值“contains”为 false。关于为什么两个对象的哈希值根据“equals”方法相等并且相等,但在 HashSet 中不包含相等的对象,有什么想法吗?
如果您以影响对象的相等性和哈希码的方式修改对象,则会出现此问题after将它们添加到 HashSet 中。该集合将发生故障,因为在哈希表的与其新值相对应的正确槽中找不到对象。
同样,如果您修改用作 HashMap 的对象,HashMap 也会发生故障。keys。与 TreeSet 和 TreeMap 类似。所有这些数据结构都可以快速定位对象,因为每个对象的值决定了它的存储位置。如果随后修改这些对象,结构就会出错。
不可变对象比集合元素和映射键更好,因为它们避免了这种复杂性。
如果必须修改属于对象相等性一部分的字段,则需要先暂时将其从集合中删除,然后再重新添加。或者,使用列表作为对象的主容器,并仅在需要时构造临时集。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)