4

申し訳ありません...このばかげた/ばかげた質問について、みんな:

なぜ適用されequals()ないのですか?hashCode()

現在、期待どおりに機能しているだけですHashSet

アップデート

EVEN キー値 5 が繰り返されますが、equals と hashCode は呼び出されません。

バリューにも適用したい。

この例で HashSet が equals と hashCode を呼び出しているのと同じように、キーの場合でも hashMap が equals と hashCode と呼ばれないのはなぜですか。

UPDATE2 - 回答

HashMap の key(class->HashCode, equals) が呼び出されます。皆さん、ありがとうございました。これには少し戸惑いました。:)

    public class Employee {

        int id;
        String name; 
        int phone;

        public Employee(int id, String name, int phone) {
            this.id = id;
            this.name = name;
            this.phone = phone;
        }    
    // Getter Setter

        @Override
        public boolean equals(Object obj) {

            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Employee other = (Employee) obj;
            System.out.println("Employee -  equals" + other.getPhone());
            if (this.id != other.id) {
                return false;
            }
            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
                return false;
            }
            if (this.phone != other.phone) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            System.out.println("Employee -  hashCode" );
            int hash = 3;
            hash = 67 * hash + this.id;
            hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
            hash = 67 * hash + this.phone;
            return hash;
        }
    }

____________________________________________________________________________________

public class MapClass {

    public static void main(String[] args) {
        Map<Integer,Employee> map = new HashMap<Integer,Employee>();
        map.put(1, new Employee(1, "emp", 981));
        map.put(2, new Employee(2, "emp2", 982));
        map.put(3, new Employee(3, "emp3", 983));
        map.put(4, new Employee(4, "emp4", 984));
        map.put(5, new Employee(4, "emp4", 984));
       **//UPDATE**
        map.put(5, new Employee(4, "emp4", 984));            

        System.out.println("Finish Map" + map.size());
        Set<Employee> set = new HashSet<Employee>();

        set.add(new Employee(1, "emp", 981));
        set.add(new Employee(2, "emp2", 982));
        set.add(new Employee(2, "emp2", 982));
        set.add(new Employee(3, "emp3", 983));
        set.add(new Employee(4, "emp4", 984));
        set.add(new Employee(4, "emp4", 984));

        System.out.println(set.size());
    }
}

出力は

Finish Map5
Employee -  hashCode
Employee -  hashCode
Employee -  hashCode
Employee -  equals982
Employee -  equals982
Employee -  hashCode
Employee -  hashCode
Employee -  hashCode
Employee -  equals984
Employee -  equals984
4
4

4 に答える 4

7

EVEN キー値 5 が繰り返されますが、equals と hashCode は呼び出されません

はい、キーの整数で hashCode を呼び出します。

Valueにも適用したい

現実の線量: Java HashMaps はそのようには機能しません。値ではなく、キーの重複のみをチェックします。これはあるべき姿です。

従業員のハッシュをマップでチェックする場合は、それがキーである必要があります。限目。

別の可能な解決策は、利用可能なマルチマップの 1 つをダウンロードすることです。

編集 して hashCode と equals を呼び出していることを確認し、Map のキー タイプを次のように変更します。

class MyInt {
   private Integer i;

   public MyInt(Integer i) {
      this.i = i;
   }

   public Integer getI() {
      return i;
   }

   @Override
   public int hashCode() {
      System.out.println("MyInt HashCode: " + i.hashCode());
     return i.hashCode();
   }

   @Override
   public boolean equals(Object obj) {
      System.out.printf("MyInt equals: [%s, %s]%n", i, obj);
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      MyInt other = (MyInt) obj;
      if (i == null) {
         if (other.i != null)
            return false;
      } else if (!i.equals(other.i))
         return false;
      return true;
   }

   @Override
   public String toString() {
      return i.toString();
   }

}

次に、マップを次のように入力します。

   Map<MyInt,Employee> map = new HashMap<MyInt,Employee>();
   map.put(new MyInt(1), new Employee(1, "emp", 981));
   map.put(new MyInt(2), new Employee(2, "emp2", 982));
   map.put(new MyInt(3), new Employee(3, "emp3", 983));
   map.put(new MyInt(4), new Employee(4, "emp4", 984));
   map.put(new MyInt(5), new Employee(4, "emp4", 984));
   map.put(new MyInt(5), new Employee(4, "emp4", 984));

次のように表示されます。

MyInt HashCode: 1
MyInt HashCode: 2
MyInt HashCode: 3
MyInt HashCode: 4
MyInt HashCode: 5
MyInt HashCode: 5
MyInt equals: [5, 5]
于 2012-05-22T12:59:38.840 に答える
3

HashMap は、キー値の equals/hashCode を使用します (あなたの場合は Integer)。それがあなたが求めていることだと思いますよね?

マップに重複があるのは、同じ従業員に新しいキーを使用しているためです。

  map.put(4, new Employee(4, "emp4", 345));
  map.put(5, new Employee(4, "emp4", 345));  // You are using 5 as the key
                                             // for the "same" object you did 
                                             // in the previous line

あなたが何かをしたなら

  // in main
  addEmployee(new Employee(4, "emp4", 345));
  addEmployee(new Employee(4, "emp4", 345));

  private void addEmployee(Employee e)
  {
     map.put(e.getId(), e);
  }

その後、コレクションに重複は表示されません。

于 2012-05-22T12:48:36.280 に答える
3

HashMap は、値ではなくキーをインデックスとして使用します。(これは hashCode() であり、上記のコードの Integer クラスで equals() が呼び出される可能性があります)

于 2012-05-22T12:48:48.940 に答える
0

a を使用しているHashMap<Integer, Employee>ように見えるので、Integers はハッシュされます。キーが1,2,3,4,5であるため、サイズはHashMap5 である必要があります。

于 2012-05-22T12:50:45.110 に答える