Java中ArrayList.contains使用问题:是否需重写equals方法?
问题解答
是否必须重写equals方法?
是的,必须重写。
原因是什么?
Java里所有类默认继承自Object类,Object的equals方法是引用比较——只有当两个对象是内存里的同一个实例时,才会返回true。你代码里每次循环都new了一个新的piece3对象,哪怕taille、couleur、forme这三个属性完全一致,它们在内存中也是不同的实例,默认equals会判定它们是不同对象,所以contains会认为“不存在”,最终导致重复对象被添加进列表。
contains方法的判断依据是什么?
ArrayList的contains方法会遍历列表中的每个元素,依次调用元素的equals方法和传入的对象做比较:只要有一个元素调用equals返回true,contains就返回true;遍历完所有元素都没匹配上,就返回false。它的核心逻辑大致如下:
public boolean contains(Object o) { return indexOf(o) >= 0; } public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
解决方法
你需要在piece3类里重写equals方法,根据taille、couleur、forme这三个属性来判断对象是否相等。按照Java规范,重写equals时最好同步重写hashCode方法(避免后续使用HashMap等集合时出现逻辑异常)。示例代码如下:
class piece3 { private boolean taille; private boolean couleur; private boolean forme; // 构造方法 public piece3(boolean taille, boolean couleur, boolean forme) { this.taille = taille; this.couleur = couleur; this.forme = forme; } // 重写equals方法 @Override public boolean equals(Object o) { if (this == o) return true; // 引用相同直接判定相等 if (o == null || getClass() != o.getClass()) return false; // 类型不同直接判定不等 piece3 target = (piece3) o; // 比较三个核心属性 return taille == target.taille && couleur == target.couleur && forme == target.forme; } // 重写hashCode方法 @Override public int hashCode() { return Objects.hash(taille, couleur, forme); } }
修改后,只要两个piece3对象的三个属性都一致,equals就会返回true,contains就能正确识别重复对象,避免重复添加。
内容的提问来源于stack exchange,提问作者cameleon
相关产品推荐
相关产品推荐

