2013-05-09 31 views
13

如果我运行下面的代码,那么输出是2,这意味着该集合包含2个元素。不过我认为该集应该包含1,因为两个对象基于hashcode()值以及.equals()方法都是相等的。 似乎在我的理解中出现了一些明显的错误?Java:添加到集合中的重复对象?

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; 
    } 
} 

回答

22

你的哈希Ç ODE方法不会覆盖Object类的哈希Ç ODE方法,因此你的equals方法中断合同,因为它不符合的hashCode结果一致,你可以有对象是“相等的”,但具有不同的hashCode。

切记:在覆盖方法时,您应始终使用@Override注释,因为这将帮助您捕获此类错误和类似错误。

@Override // ** don't forget this annotation 
public int hashCode() { // *** note capitalization of the "C" 
    return a; 
} 

此外,您需要改进您的代码格式,特别是在此处发布代码以供我们审核时。如果符合标准,我们将能够更好地理解您的代码并为您提供帮助(这就是标准存在的原因)。因此,请尽量保持缩进与同一块中缩进相同级别的所有代码行保持一致,并且您需要确保基本级代码(包括导入,外部类声明和其结束大括号)左对齐:

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; 
    } 
} 

有关这个美丽的,请阅读:Overriding equals and hashCode in Java

+0

谢谢!永远不会忘记使用@Override :) – 2013-05-09 16:33:59

+0

@snow_leopard:这是一个很好的习惯。祝你好运! – 2013-05-09 16:38:25

+0

除了“@Override”之外,我还必须在equals函数中添加一行,否则该集无法检测到重复项,并始终包含多次具有相同内容的对象:if(this.hashCode()== msg。 hashCode()) return true; – 2015-01-21 08:32:33

3

的@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; 
} 
4

您方法公顷shcode应该被命名为hashCode(大写字母“C”)。

如果您计划重写方法,则应使用@Override注释。

如果您已经使用了该注释,那么您之前会注意到该问题,因为该代码不会编译。

相关问题