Java:重复的对象被添加到集合中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16462644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: Duplicate objects getting added to set?
提问by snow_leopard
If I run the below code then the output is 2 which means that the set contains 2 elements. However I think that set should contain 1 since both the objects are equal based on hashcode()value as well as .equals()
method.
Seems like some obvious mistake in my understanding ?
如果我运行以下代码,则输出为 2,这意味着该集合包含 2 个元素。但是我认为该集合应该包含 1,因为基于hashcode()值和.equals()
方法,两个对象都是相等的。在我的理解中似乎有一些明显的错误?
package HELLO;
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) throws Exception {
Set<Alpha> s = new HashSet<Alpha>();
Alpha a1 = new Alpha();
Alpha a2 = new Alpha();
s.add(a1);
s.add(a2);
System.out.println(s.size());
}
}
class Alpha {
int a = 10;
public int hashcode() {
return a;
}
public boolean equals(Object obj) {
return (obj instanceof Alpha && ((Alpha) obj).a == this.a);
}
public String toString() {
return "Alpha : " + a;
}
}
采纳答案by Hovercraft Full Of Eels
Your hashcode method does not override the Object class's hashCode method and thus your equals method breaks contract since it doesn't agree with the hashCode results, and you can have objects that are "equal" but have different hashCodes.
你的散列çODE方法不会覆盖Object类的哈希ÇODE方法,因此你的equals方法中断合同,因为它不符合的hashCode结果一致,你可以有是“平等”,但有不同的哈希码的对象。
Remember: You should always use the @Override
annotation when overriding methods as this will help you catch this and similar errors.
请记住:@Override
在覆盖方法时应始终使用注释,因为这将帮助您捕获此错误和类似错误。
@Override // ** don't forget this annotation
public int hashCode() { // *** note capitalization of the "C"
return a;
}
Also, you will want to improve your code formatting, especially when posting code here for our review. We will be able to better understand your code and help you if it conforms to standards (that's why standards exist). So try to keep your indentations consistent with all code lines that are in the same block indented at the same level, and you will want to be sure that base level code, including imports, outer class declarations and its end curly brace, is flush left:
此外,您将希望改进代码格式,尤其是在此处发布代码以供我们审核时。如果它符合标准,我们将能够更好地理解您的代码并为您提供帮助(这就是标准存在的原因)。所以尽量让你的缩进与在同一级别缩进的同一块中的所有代码行保持一致,并且你需要确保基本级别的代码,包括导入、外部类声明和它的结束大括号,是左对齐的:
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) throws Exception {
Set<Alpha> s = new HashSet<Alpha>();
Alpha a1 = new Alpha();
Alpha a2 = new Alpha();
s.add(a1);
s.add(a2);
System.out.println(s.size());
}
}
class Alpha {
int a = 10;
@Override
public int hashCode() {
return a;
}
public String toString() {
return "Alpha : " + a;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Alpha other = (Alpha) obj;
if (a != other.a)
return false;
return true;
}
}
For a beautiful review on this, please read: Overriding equals and hashCode in Java
有关这方面的精彩评论,请阅读:在 Java 中重写 equals 和 hashCode
回答by Suresh Atta
The @Overrides annotation is to override the method with the same name in the super class".
@Overrides 注解就是覆盖超类中的同名方法”。
@Override
public int hashCode() {
return a;
}
@Override
public boolean equals(Object obj) {
return (obj instanceof Alpha && ((Alpha) obj).a == this.a);
}
@Override
public String toString() {
return "Alpha : " + a;
}
回答by Mena
your method hashcodeshould be named hashCode(capital letter "C").
您的方法哈希码应命名为hashCode(大写字母“C”)。
If you plan on overriding methods you should use the @Override
annotation.
如果您计划覆盖方法,则应使用@Override
注释。
If you had used that annotation, you'd have noticed the problem earlier as the code wouldn't have compiled.
如果您使用了该注释,那么您会更早地注意到这个问题,因为代码不会被编译。