大家看看我这代码打印equals是为什么,我想不通.第二次打印了两次更我想不通,
import java.util.HashSet;   
import java.util.Set;   
public class lessons2 {     
  public static void main(String[] args) {    
    testForHashSet2();   
  }   
  public static void testForHashSet2() {   
    System.out.println("----- testForHashSet2 -----------");   
    HashSet<MyObject2> set = new HashSet<MyObject2>();   
    MyObject2 obj = null;   
    for (int i = 0; i < 3; i++) {   
      obj = new MyObject2("java2000" + i, i);   
      set.add(obj);   
      System.out.println(set.size()+obj.getName());   
    }   
  }  

class MyObject2 {   
  private int age;   
  private String name;   
  
  public int getAge() {   
    return age;   
  }    
  public void setAge(int age) {   
    this.age = age;   
  }     
  public String getName() {   
    return name;   
  }    
  public void setName(String name) {   
    this.name = name;   
  }    
  MyObject2(String name, int age) {   
    this.name = name;   
    this.age = age;   
  }   
  public boolean equals(Object obj) {   
    System.out.println(",,equals");   
    if (obj == null || !(obj instanceof MyObject2)) {   
      return false;   
    }   
    MyObject2 o = (MyObject2) obj;   
    return this.age == o.age && this.name.equals(o.name);   
  }   
  
  public int hashCode() {   
    return 1;   
  }   
}  

解决方案 »

  1.   

    打印结果:
    ----- testForHashSet2 -----------
    1java20000
    ,,equals
    2java20001
    ,,equals
    ,,equals
    3java20002
      

  2.   

    谢谢,我还有点问题,我是重写了equals方法,但是我没有使用
    ,另外它为什么在java2000这后出现,而不是在这之前出现
    还有2java20001之后为什么它就特殊出现两个呢
      

  3.   

    hashset调用对象的equals方法来比较对象是否是同一个,来实现hashset集合中对象的唯一性,在你调用add方法时,都需要遍历一次该集合调用equasls方法进行比较看是否有重复对象,因此你没有显示调用equals方法却显示出了equals方法里打印的内容。集合里有几个对象则要比较几次,因此你第一次add时集合里面没有对象,因此没有比较;第二次时需要将添加的对象与集合中已存在的对象对比,此时比较一次;第三次,则比较2次,打印两条。
      

  4.   

    可以自己在set.add(obj);那里设断点,然后debug看看就知道(可以清楚看见调用你的equals的过程)
    在put的时候他不是随便就put的,它还要比较key是不是相等了
    所以就调用了equals方法,每次put都要检查一下
    因为Map的key不能重复
      

  5.   

    第一次,没有对象,所以不用对比,直接输出1java20000 
    第二次,里面有一个对象,调用一次equals方法,所以输出一次,,equals 再输出2java20001
    第三次,里面有两个对象,调用二次equals方法,所以输出两次,,equals 再输出3java20002 
      

  6.   

    这是原因   
    如果楼主不想打印equals,可以吧hashcode方法重写一下,如下:
             @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + age;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
    }打印结果:
    ----- testForHashSet2 -----------
    1java20000
    2java20001
    3java20002
      

  7.   

    补充一下,hashset添加元素是先判断hashcode的值是不是相同,如果不相同直接添加,如果相同的话再比较equals方法,不相同添加,相同不添加
      

  8.   

    这个是不对的,hashset添加对象的时候是调用equals方法进行比较,只是equals默认实现是比较hashcode是否一致,一致则相等。所以如果重写了equals方法再去重写hashcode方法其实没意义了。import java.util.HashSet;  
    import java.util.Set;  
    public class TestHashSet {    
      public static void main(String[] args) {    
        testForHashSet2();  
      }  
      public static void testForHashSet2() {  
        System.out.println("----- testForHashSet2 -----------");  
        HashSet  set = new HashSet();  
        MyObject2 obj = null;  
        for (int i = 0; i < 3; i++) {  
          obj = new MyObject2("java2000" + i, i);  
          set.add(obj);  
          System.out.println(set.size()+obj.getName());  
        }  
      }  

    class MyObject2 {  
      private int age;  
      private String name;  
      
      public int getAge() {  
        return age;  
      }    
      public void setAge(int age) {  
        this.age = age;  
      }    
      public String getName() {  
        return name;  
      }    
      public void setName(String name) {  
        this.name = name;  
      }    
      MyObject2(String name, int age) {  
        this.name = name;  
        this.age = age;  
      }  
      public boolean equals(Object obj) {  
        System.out.println(",,equals");  
        if (obj == null || !(obj instanceof MyObject2)) {  
          return false;  
        }  
        MyObject2 o = (MyObject2) obj;  
        return this.age == o.age && this.name.equals(o.name);  
      }  
      
      public int hashCode() {  
        return this.name.hashCode() + this.age * 1000; //确保当名字和年龄不相同时hashcode不同,与 equals方法实现一致
      }  
    }  这个程序的输出还是
    ----- testForHashSet2 -----------
    1java20000
    2java20001
    3java20002
    说明即使hashcode不一样,还是调用了equals方法
      

  9.   

      public boolean equals(Object obj) {  
        System.out.println(",,equals");  
        if (obj == null || !(obj instanceof MyObject2)) { //看这里,如果equals()方法被调用,将打印 ,,equals,然而结果中没有打印!!
          return false;  
        }  
        MyObject2 o = (MyObject2) obj;  
        return this.age == o.age && this.name.equals(o.name);  
      }