在学习《Thinking in Java》中的关于容器一章时,明显书中丢失了用自定义类填充Set时的一部分代码——即被填充的类型代码。我参照JDK API doc写了一个类型MyType,实现了Comparable接口的compareTo()方法,也定义了equals(),并且调试结果正确,可是MyType的两个同值(用m1.equals(m4)调用返回true)的实例m1 和m4,分别执行Set的add()方法,结果Set中还是填充了两个元素,并不是预期的应该只有一个。以下是我的代码:
//: c11:Set2.java
// Putting  own type in a Setimport java.util.*;class MyType implements Comparable {
  int i = 0;
  public MyType() { this(1); }
  public MyType(int i) {
    this.i = i;
  }
  public int compareTo(Object m) {
    int mi = ((MyType)m).i;
    return ( i < mi ? -1 : ( i == mi ? 0 : 1));
  }
  public String toString() {
    return "" + i;
  }
  public boolean equals(Object m) {
    if(i == ((MyType)m).i)
      return true;
    else
      return false;
  }
}public class Set2 {
  public static void main(String[] args) {
    MyType m1 = new MyType(1);
    MyType m2 = new MyType(2);
    MyType m3 = new MyType(3);
    MyType m4 = new MyType(1);    // Test compareTo() func
    System.out.println("m1.compareTo(m2) = " + m1.compareTo(m2));
    System.out.println("m2.compareTo(m3) = " + m2.compareTo(m3));
    System.out.println("m3.compareTo(m1) = " + m3.compareTo(m1));
    System.out.println("m2.compareTo(m2) = " + m2.compareTo(m2));
    // Test equals() func
    System.out.println("m1.equals(m4) = " + m1.equals(m4)); 
    Set s = new LinkedHashSet();
    s.add(m1);
    s.add(m2);
    s.add(m3);
    System.out.println("s.contains(m1) = " + s.contains(m1));
    System.out.println("s.contains(m4) = " + s.contains(m4));
    s.add(m4);
    System.out.println(s);
    s.add(m1);
    System.out.println(s);
  }
}
///:~结果是Set扔把同值的对象分别加入了进去,困惑,希望大家帮个忙,谢谢

解决方案 »

  1.   

    http://www.javathinker.org/main.jsp?bc=showessay.jsp&filename=hibernate/hibernate_essay_11.htm
      

  2.   

    谢谢指点,明白了。
        除了TreeSet不需要hashCode()方法来判断唯一性以外,HashSet及其子类都需要hashCode()方法与compareTo()与equals()共同判断唯一性。所以后者中存储的类型一定要正确实现这三种方法。
        而且我感觉好的编程风格,应该在覆盖equals()方法的同时,就应该同时覆盖hashCode()方法。
        再次谢谢gtlang78。
      

  3.   

    除了实现equals(),还需要一个hashCode()