要求该类可以充当 的键HashMap,为此您需要重写其方法hashcode,equals以便履行这些重写方法之间的约定。问题是该类只有一个 ArrayList 类型的字段。
底漆:
public class ObjectBox {
List collection;
/**
* Instantiates a new Object box.
*/
public ObjectBox() {
this.collection = new ArrayList<>();
}
ObjectBox(final Object[] array) {
collection = Arrays.asList(array);
Collections.sort(collection);
}
/**
* Add a new Element to Collection
*
* @param o the Object
*/
public void add(final Object o){
collection.add(o);
}
/**
* Deletes a given Object
* in existing Data
*
* @param o the Object
*/
public void delete(final Object o){
collection.remove(o);
}
//TODO
@Override
public int hashCode() {
return super.hashCode();
}
//TODO
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public String toString() {
return super.toString();
}
}
如果我以这种方式覆盖该方法是否正确:
@Override
public int hashCode() {
int result = 31;
result = 17 * result + (collection != null ? collection.hashCode() : 0);
return result;
}
让它更容易:
引擎盖下将是这样的:
如果 ObjectBox 是 HashMap 中的键,那么它无论如何都不正确。键必须是不可变/不可变的,这在上面的代码中没有观察到。修改key后,修改了hashCode,这个key在HashMap中就找不到了。
当向 HashSet 添加新元素或向 HashMap 添加键值对时,hashCode 值用于查找将放置对象引用的“桶”(原始桶)。搜索对象时,将再次使用 hashCode,但这次是查找对象应该在的“篮子”,之后“篮子”中的所有对象将使用 equals 方法与所需的对象进行比较。因此,更改 hashCode 会导致在另一个“篮子”中搜索元素,并且找不到匹配项,这将是程序逻辑错误的根源。在这种情况下,对象的引用将出现在 HashMap/Set 中,这就是 GC 不会删除它的原因,这已经导致内存泄漏。
错误演示: