Javaカスタムオブジェクトをマップのキーとして使用する場合、equals()メソッドとhashCode()メソッドを書き直す必要があります。
IDEAは、Javaクラスのequals()メソッドとhashCode()メソッドをすばやく書き換えることができます。
Lombokの@Dataアノテーションは、Javaクラスのequals()メソッドとhashCode()メソッドを自動的に生成できます。@ Dataアノテーションを使用すると、次のアノテーションが自動的に追加されます。
- @Getter
- @セッター
- @RequiredArgsConstructor
- @ToString
- @EqualsAndHashCode
@Dataは、@ Getter、@ Setter、@ RequiredArgsConstructor、@ ToString、および@EqualsAndHashCodeの5つのアノテーションのコレクションに相当します。その中で、@ EqualsAndHashCodeアノテーションの機能は、Javaクラスのequals()メソッドとhashCode()メソッドを書き直すことです。詳細については、@ EqualsAndHashCodeの公式Webサイトを参照してください。
公式サイトのドキュメントには、おおまかに次の点が記載されています。
- このアノテーションは、equals(Object other)メソッドとhashCode()メソッドを生成します。
- デフォルトでは、非静的、非一時的なプロパティを使用します。
- 一部の属性は、パラメーターExcludeを使用して除外できます。
- パラメータIncludeを使用して、使用する属性を指定できます。
- デフォルトでは、クラスで定義された属性のみを使用し、親クラスのメソッドを呼び出しません。
- 上記の問題は、@ EqualsAndHashCode(callSuper = true)によって解決できます。生成されたメソッドが親クラスのメソッドを呼び出すようにします。
テストクラスとテストメソッドは次のとおりです。
package com.test.model;
import lombok.Data;
@Data
public class Student {
// 姓名
private String stuNm;
// 年龄
private String age;
// 构造函数
public Student(String stuNm, String age) {
this.stuNm = stuNm;
this.age = age;
}
}
package com.test.model;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<Student, String> map = new HashMap<>();
Student stuA = new Student("张三", "20");
map.put(stuA, "95");
Student stuB = new Student("张三", "21");
map.put(stuB, "93");
System.out.println(map.get(stuA)); // 95
System.out.println(map.get(stuB)); // 93
Student stuC = new Student("张三", "20");
System.out.println(map.get(stuC)); // 95
System.out.println(stuA.equals(stuC)); // true
System.out.println(stuA.hashCode() == stuC.hashCode()); // true
}
}
stuAとstuCの名前と年齢は同じであるため、書き直されたequals()とhashCode()によると、stuA.equals(stuC)とstuAとstuCのhashCode値は同じです。