우리는 모두 Java 언어가 완전히 객체 지향적이라는 것을 알고 있습니다. Java에서는 모든 객체가 객체 클래스에서 상속됩니다.
Equals 메소드는 지적 된 주소를 두 객체의 참조로 비교합니다. 해시 코드는 로컬 메소드이며 객체 주소 값을 반환합니다. OjBect 클래스에는 동등한 두 가지 방법과 해시 코드가 있습니다. 이 두 가지 방법은 두 객체의 동일인지 비교하는 데 사용됩니다.
Equals 메소드를 다시 작성하는 동안 해시 코드 메소드를 무시 해야하는 이유는 무엇입니까?
다음과 같이 이해할 수 있습니다. Equals 메소드를 다시 쓰면 물체의 평등을 판단하기위한 비즈니스 논리가 변경됩니다. 클래스의 디자이너는 메모리 주소를 비교하여 두 객체 평등을 비교하고 싶지 않습니다. 주소에 따라 계속 비교하는 것은 의미가 없습니다. 따라서 단순히 함께 변경됩니다.
또 다른 이유는 컬렉션에서 나옵니다. 아래에서 천천히 이야기합시다 ~
예를 들어:
학교에서는이 사람이 속한 지 여부를 결정하는 것이 학생 신분증을 통해입니다.
아래 코드의 시나리오는 학생 기록 입력, 학생 번호 123은 학생 Tom에 할당되며, 학생 번호 456은 학생 Jerry에게 할당되며 학생 번호 123은 실수로 Lily에 할당됩니다. 그러나 학생 지위를 등록하는 과정에서 동일한 학생 번호가 발생해서는 안됩니다.
상황 요구 사항에 따라 중복 객체를 추가 할 수 없으며 해시 세트를 통해 구현할 수 있습니다.
공개 클래스 테스트 {public static void main (String [] args) {학생 stu = new student (123, "tom"); Hashset <tudent> set = new Hashset <> (); set.add (stu); set.add (456, "Jerry"); set.add (new Student (123, "릴리"); while (iterator.hasnext ()) {학생 student = iterator.next (); System.out.println (whening.getStunum () + "---" + Student.getName ());}}}; 클래스 학생 {private int stunum; 개인 문자열 이름; 공개 학생 (int stunum, String Name) {this.stunum = this.name = name;} public int getstunum () {public string getname ()}} name;}@atrementpublic boolean equals (object obj) {if (this == obj) return true; if (obj instance of student) {if (this.getStunum () == ((학생) obj) .getStunum ())} 반환 거짓;}}. 출력은 다음과 같습니다.
123 --- 릴리
456 --- Jerry
123 --- 톰
출력을 바탕으로, 우리는 학생 번호 123을 Lily에 다시 할당하는 것이 성공했다는 것을 알았습니다. 무엇이 잘못 되었습니까?
해시 세트의 추가 방법을 살펴 보겠습니다.
public boolean add (e e) {return map.put (e, present) == null;} 실제로 Hashset은 Hashmap을 통해 구현되므로 Hashmap의 PUT 방법을 추적합니다.
public v put (k key, v value) {if (table == emply_table) {inflatetable (threshold);} if (key == null) return putfornullkey (value); int hash = hash (key); int i = indexfor (hash, table.length); for (enth <k, v> e = table [e! = e. hash && (k = e.key) == key || key.equals (k)))) {v OldValue = e.value; e.value = value; e.recordAccess (this); returnvalue;}} modcount ++;1. 키에 따르면, 즉 해시 세트에 의해 추가 될 객체, 해시 코드를 가져 오며 해시 코드는 해시 코드를 얻기 위해 특정 비트 작업을 수행하는 데 사용됩니다.
2. 해시 코드 포지셔닝을 사용하여 링크 된 목록의 링크 헤더를 가져 오기 위해 배열 위트 스크립트를 찾으십시오.
3. 링크 된 목록을 통과하여 동일한 키가 있는지 확인하십시오. 판단의 기초는 e.hash == hash && ((k = e.key) == key || key.equals (k))입니다. Lily를 추가 할 때, Equals 방법이 다시 작성되기 때문에 Tom을 가로 질러 두 번째 조건이 참 이루야합니다. 그러나 해시 코드 메소드는 여전히 상위 클래스를 사용하기 때문에 Tom과 Lily의 해시 코드는 다릅니다. 즉, 해시 코드는 다르고 첫 번째 조건은 False입니다. 여기서 우리는 두 객체가 다르므로 해시 세트는 Lily를 성공적으로 추가합니다.
그 이유는 해시 코드 메소드가 다시 작성되지 않기 때문입니다. 수정은 다음과 같습니다.
공개 클래스 테스트 {public static void main (String [] args) {학생 stu = new student (123, "tom"); Hashset <tudent> set = new Hashset <> (); set.add (stu); set.add (456, "Jerry"); set.add (new Student (123, "릴리"); while (iterator.hasnext ()) {학생 student = iterator.next (); System.out.println (whening.getStunum () + "---" + Student.getName ());}}}; 클래스 학생 {private int stunum; 개인 문자열 이름; 공개 학생 (int stunum, String Name) {this.stunum = this.name = name;} public int getstunum () {public string getname ()}} name;}@atrementpublic boolean equals (object obj) {if (this == obj) return true; if (obj instance of student) {if (this.getStunum ((학생) obj) .getStunum ())} return false;}@attormspublic int hashcode () {return getstunum ();}}}} 산출:
456 --- Jerry
123 --- 톰
해시 코드 방법을 다시 작성하고 학생 번호를 반환하십시오. 좋아, 끝났어.
어떤 사람들은 e.hash == hash && ((k = e.key) == key || key.equals (k))가 약간 복잡합니까? 나는 단지 평등 방법을 사용하는 것으로 충분하다고 생각합니다. 한 번에 해시 코드를 판단 해야하는 이유는 무엇입니까?
해시 맵의 링크 된 목록 구조에서 통과하고 판단 할 때, 다시 작성된 평등 메소드의 비즈니스 로직은 특정 상황에서 객체가 동일하고 루프 다운의 비즈니스 논리가 검색 효율에 영향을 미치기 위해 더 복잡하기 때문에 더욱 복잡하기 때문입니다. 그래서 여기서 우리는 해시 코드의 판단을 최우선으로 생각합니다. 해시 코드가 같지 않으면 재생을 마치고 더 이상 복합체 평등을 호출 할 필요가 없습니다. 해시 맵의 효율성을 크게 향상시킵니다.
따라서 해시 코드 방법은 해시 맵과 같은 컬렉션 클래스를 정상적으로 사용할 수 있도록하는 것입니다. 해시 맵은 객체가 해시 코드와 비교와 동일합니다. 이 구현은 해시 맵의 효율성을 향상시키는 것입니다.