Java에서 equals 메서드와 hashCode 메서드를 덮어쓸 필요가 있는 이유는 무엇입니까?
최근에 이 Developer Works 문서를 읽었습니다.
에서는 '어느 때 보다'를 정의하는 입니다.hashCode()
★★★★★★★★★★★★★★★★★」equals()
효과적이고 정확하게, 하지만 왜 우리가 이 두 가지 방법을 재정의해야 하는지 이해할 수 없습니다.
이러한 방법을 효율적으로 구현하려면 어떻게 해야 합니까?
효과적인 자바에 대해 Joshua Bloch가 말합니다.
equals()를 덮어쓰는 모든 클래스에서 hashCode()를 덮어써야 합니다.그렇지 않으면 객체에 대한 일반 계약을 위반하게 됩니다.hashCode(): 클래스가 HashMap, HashSet 및 Hashtable을 포함한 모든 해시 기반 컬렉션과 함께 올바르게 작동하지 않도록 합니다.
.equals()
하지 않고hashCode()
해서 한 번 .Map
.
, 두가 있다, 클래스가 있다고 칩시다.그리고 두 개의 오브젝트가 있습니다.MyClass
동일할 경우importantField
hashCode()
★★★★★★★★★★★★★★★★★」equals()
★★★★★★★★★★★★★★★★★★★★★★★」
public class MyClass {
private final String importantField;
private final String anotherField;
public MyClass(final String equalField, final String anotherField) {
this.importantField = equalField;
this.anotherField = anotherField;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((importantField == null) ? 0 : importantField.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MyClass other = (MyClass) obj;
if (importantField == null) {
if (other.importantField != null)
return false;
} else if (!importantField.equals(other.importantField))
return false;
return true;
}
}
이걸 가지고 있다고 생각해 보세요.
MyClass first = new MyClass("a","first");
MyClass second = new MyClass("a","second");
""만 "equals
다다 if ifequals
되어 되 call is is is is is is is is is is is is is is is 。myMap.put(first,someValue)
, 을 하면myMap.put(second,someOtherValue)
양동이)로.hashCode
동일하지만 같은 버킷으로 해시되지 않기 때문에 맵은 이를 인식하지 못하고 둘 다 맵에 남습니다.
「」를 덮어쓸 만,equals()
「」를 무효로 hashCode()
이 경우 이 경우 두 가지 오브젝트는MyClass
동일할 경우importantField
하지만, .equals()
.
""만 "hashCode
「」만 .hashCode
를 호출했을 때.」를 해 주세요.myMap.put(first,someValue)
번째를 하여 '''를 합니다.hashCode
지정된 버킷에 저장합니다. 나서, 이 전화했을 때.myMap.put(second,someOtherValue)
(비즈니스 요건에 따라) 동일하기 때문에 지도 설명서에 따라 첫 번째를 두 번째로 대체해야 합니다.
문제는 이 해시될 때 등호가 재정의되지 않았다는 입니다. 그래서 지도 해시가second
하여 오브젝트가 합니다.k
second.equals(k)
수 second.equals(first)
되다false
.
잘 됐으면 좋겠는데
음음음 as as 의 컬렉션HashMap
★★★★★★★★★★★★★★★★★」HashSet
오브젝트의 해시 코드 값을 사용하여 컬렉션 내에 저장하는 방법을 결정하고, 해시 코드를 다시 사용하여 컬렉션 내의 오브젝트를 찾습니다.
해시 취득은 2단계 프로세스입니다.
- (「」를 사용).
hashCode()
) - 요소를 합니다(「」를 사용).
equals()
)
에서는 왜 해야 하는가에 작은 를 제시하겠습니다.equals()
★★★★★★★★★★★★★★★★★」hashcode()
.
「 」를 .Employee
나이와 이름의 두 개의 필드가 있는 클래스입니다.
public class Employee {
String name;
int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
Java에서 equals 메서드와 hashCode 메서드를 덮어쓸 필요가 있는 이유는 무엇입니까? }
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Employee))
return false;
Employee employee = (Employee) obj;
return employee.getAge() == this.getAge()
&& employee.getName() == this.getName();
}
// commented
/* @Override
public int hashCode() {
int result=17;
result=31*result+age;
result=31*result+(name!=null ? name.hashCode():0);
return result;
}
*/
}
클래스를 , '클래스'를 삽입하고,Employee
를 제기하다HashSet
그 물체가 존재하는지 여부를 테스트합니다.
public class ClientTest {
public static void main(String[] args) {
Employee employee = new Employee("rajeev", 24);
Employee employee1 = new Employee("rajeev", 25);
Employee employee2 = new Employee("rajeev", 24);
HashSet<Employee> employees = new HashSet<Employee>();
employees.add(employee);
System.out.println(employees.contains(employee2));
System.out.println("employee.hashCode(): " + employee.hashCode()
+ " employee2.hashCode():" + employee2.hashCode());
}
}
다음과 같이 인쇄됩니다.
false
employee.hashCode(): 321755204 employee2.hashCode():375890482
언코멘트입니다.hashcode()
은 method, 음음음음음음음 음음음음음 음음음 method method method method method method method method 。
true
employee.hashCode(): -938387308 employee2.hashCode():-938387308
두 개체가 동일한 것으로 간주될 경우 해시 코드도 동일해야 하는 이유를 알 수 있습니까?그렇지 않으면 클래스 객체의 기본 해시 코드 메서드는 실질적으로 각 객체에 대해 고유한 번호를 항상 표시하므로 객체를 찾을 수 없습니다.equals()
메서드는 두 개 이상의 개체가 동일한 것으로 간주되도록 재정의됩니다.해시 코드가 이를 반영하지 않는 경우 객체가 얼마나 동일한지는 중요하지 않습니다.다시 한 번 말씀드리겠습니다.두 객체가 동일한 경우 해시 코드도 같아야 합니다.
equals()를 덮어쓰는 모든 클래스에서 hashCode()를 덮어써야 합니다.그렇지 않으면 객체에 대한 일반 계약을 위반하게 됩니다.hashCode(): 클래스가 HashMap, HashSet 및 Hashtable을 포함한 모든 해시 기반 컬렉션과 함께 올바르게 작동하지 않도록 합니다.
유효한 자바에서, Joshua Bloch에 의해
「」를 equals()
★★★★★★★★★★★★★★★★★」hashCode()
일관되게 해시 기반 컬렉션의 키로서 클래스의 사용성을 향상시킬 수 있습니다.이는 hashCode API가 을 위해 됩니다."java.util.Hashtable
이러한 방법을 효율적으로 구현하는 방법에 대한 질문에 대한 가장 좋은 답변은 효과적인 Java의 3장을 읽는 것을 권장합니다.
정체성은 평등하지 않다.
- 연산자 " " "
==
아이디 ★★★★★★★★★★★★★★★★★★★. equals(Object obj)
방법은 동등성 테스트 비교(즉, 방법을 재정의하여 동등성을 확인해야 함)
Java에서 equals 메서드와 hashCode 메서드를 덮어쓸 필요가 있는 이유는 무엇입니까?
우선 동등한 방법의 사용법을 이해해야 합니다.
두 개체 간의 차이를 식별하기 위해 동일한 방법을 재정의해야 합니다.
예를 들어 다음과 같습니다.
Customer customer1=new Customer("peter");
Customer customer2=customer1;
customer1.equals(customer2); // returns true by JVM. i.e. both are refering same Object
------------------------------
Customer customer1=new Customer("peter");
Customer customer2=new Customer("peter");
customer1.equals(customer2); //return false by JVM i.e. we have two different peter customers.
------------------------------
Now I have overriden Customer class equals method as follows:
@Override
public boolean equals(Object obj) {
if (this == obj) // it checks references
return true;
if (obj == null) // checks null
return false;
if (getClass() != obj.getClass()) // both object are instances of same class or not
return false;
Customer other = (Customer) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name)) // it again using bulit in String object equals to identify the difference
return false;
return true;
}
Customer customer1=new Customer("peter");
Customer customer2=new Customer("peter");
Insteady identify the Object equality by JVM, we can do it by overring equals method.
customer1.equals(customer2); // returns true by our own logic
이제 hashCode 메서드는 쉽게 이해할 수 있습니다.
hashCode는 HashMap, HashSet 등의 데이터 구조에 객체를 저장하기 위해 정수를 생성합니다.
합니다.Customer
와 같이
customer1.equals(customer2); // returns true by our own logic
버킷에 개체를 저장할 때 데이터 구조로 작업하는 동안 버킷은 폴더의 멋진 이름입니다.내장 해시 기술을 사용하면 2개 이상의 고객에 대해 2개의 다른 해시 코드를 생성합니다.그래서 우리는 같은 물체를 두 개의 다른 장소에 저장하고 있습니다.이러한 문제를 피하기 위해서는 다음 원칙에 따라 hashCode 메서드를 덮어쓸 필요가 있습니다.
- unsigned 인스턴스의 해시 코드가 같을 수 있습니다.
- 동일한 인스턴스는 동일한 해시 코드를 반환해야 합니다.
「」를 덮어쓰는 equals()
Java에서는 ==, +=, -+와 같은 연산자의 동작을 오버로드할 수 없습니다.그들은 특정한 방식으로 행동하고 있다.여기서는 연산자 ==에 초점을 맞추겠습니다.
연산자 ==의 작동 방식.
비교한 2개의 참조가 메모리 내의 같은 인스턴스를 가리키는지 여부를 확인합니다. ★★★★★★★★★★★★★★★」==
는 이들 2개의 참조가 메모리 내의 동일한 인스턴스를 나타내는 경우에만 true로 해결됩니다.
이제 다음 예를 살펴보겠습니다.
public class Person {
private Integer age;
private String name;
..getters, setters, constructors
}
예를 들어 프로그램에서 2개의 개인 객체를 다른 장소에 구축하여 비교한다고 가정합니다.
Person person1 = new Person("Mike", 34);
Person person2 = new Person("Mike", 34);
System.out.println ( person1 == person2 ); --> will print false!
비즈니스 관점에서 보면 이 두 가지 사물이 똑같아 보이죠?JVM을 이용하다다 둘둘 since with with with with with with 로 만들어졌기 new
키워드를 지정하면, 이러한 인스턴스는 메모리의 다른 세그먼트(segment)에 있습니다.따라서 연산자 ==가 false를 반환합니다.
그러나 == 연산자를 재정의할 수 없는 경우 JVM에 두 개체를 동일하게 취급하고 싶다고 어떻게 말할 수 있습니까? the는 the the 가 온다..equals()
이치노
덮어쓸 수 있습니다.equals()
일부 객체의 값이 동일한지 여부를 확인합니다.
비교할 필드를 선택할 수 있습니다.2개의 Person 객체가 동일한 기간과 이름을 가진 경우에만 동일하다고 하면 IDE는 다음과 같은 equal() 자동 생성을 위해 작성합니다.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
name.equals(person.name);
}
이전 예시로 돌아가 보겠습니다.
Person person1 = new Person("Mike", 34);
Person person2 = new Person("Mike", 34);
System.out.println ( person1 == person2 ); --> will print false!
System.out.println ( person1.equals(person2) ); --> will print true!
그래서 우리는 == 사업자 개체가 우리가 원하는 방법을 비교하여지만 자바를 다른 방법을 주었다에 과부하가 될 수 없는따라서 == 연산자가 원하는 방식으로 객체를 비교하도록 과부하를 걸 수 없지만 Java는다른 방법인.equals()
방법으로 우리가 원한다면 우리는 재정의할 수 있습니다.우리가 원하는 대로 덮어쓸 수 있는 방식입니다.
단, 커스텀버전을 제공하지 않는 경우는 주의해 주십시오..equals()
우리 반에(aka를 재정의하여)다음에 정의된(일명 오버라이드)우리반에서 사전 정의된..equals()
Object클래스와오브젝트 클래스에서에서==
교환은 정확히 같은 행동하리라고 확신한다.연산자도 똑같이 동작합니다.
기본 체납equals()
방법은 개체에서 상속됨은 모두 비교해 인스턴스가 메모리에서 똑같다 확인할 것이다!개체에서 상속된 메서드는 비교된 두 인스턴스가 메모리에서 동일한지 여부를 확인합니다.
왜 우리는 이유 덮어쓰는을 재정의하hashCode()
method방법
자바의 일부 데이터 구조물 HashSet처럼 HashMap 그들의 요소는 해당는 요소에 적용되는 해시 기능에 따라 저장한다.HashSet, HashMap과 같은 Java의 일부 데이터 구조는 이러한 요소에 적용되는 해시 함수를 기반으로 요소를 저장합니다.해시 기능은해시 함수는.hashCode()
할 수 있는 .equals()
하는 방법을 .hashCode()
. 이유가 거기에는 이유가 있다.
" " " 」hashCode()
개체에서 상속되는 메모리 내의 모든 개체가 고유하다고 간주됩니다.
해시 데이터 구조로 돌아가 봅시다.이러한 데이터 구조에는 규칙이 있습니다.
HashSet에는 중복된 값을 포함할 수 없으며 HashMap에는 중복된 키를 포함할 수 없습니다.
HashSet은 HashMap의 각 값이 키로 저장되는 백그라운드에서 HashMap과 함께 구현됩니다.
따라서 HashMap의 구조를 이해해야 합니다.
간단히 말해 HashMap은 버킷이 몇 개 있는 네이티브 배열입니다."linked List" 입니다.링크 리스트은 HashMap을 적용하여 각에 대해 .hashCode()
하여 method를 적용합니다.equals()
메서드를 사용하여 해당 요소가 이미 포함되어 있는지 확인합니다.이치노
HashMap listslists linkedLists 、 hash hash hash hash hash 。는 "linkedList"의 .hashCode()
메서드를 지정합니다. 만약 '만약에'가key1.hashCode()
4면 되다."key1" "4" "linked List" "linked List" "key1" "4"
로는 " " 입니다.hashCode()
방법 「」가 되어 있는 .equals()
==아니다 메모리의 모든 인스턴스를 다른 개체로 간주합니다. 제가없없 없없없다다
그러나 이전 예에서는 사용자 인스턴스의 존속 기간과 이름이 일치하는 경우 동일한 것으로 간주하고 싶다고 말했습니다.
Person person1 = new Person("Mike", 34);
Person person2 = new Person("Mike", 34);
System.out.println ( person1.equals(person2) ); --> will print true!
이제 이러한 인스턴스를 키로 저장하기 위한 맵을 만들고 일부 문자열을 쌍 값으로 지정합니다.
Map<Person, String> map = new HashMap();
map.put(person1, "1");
map.put(person2, "2");
.hashCode
.equals
디폴트로는 「」이기 에, 「」hashCode
있습니다.person1.hashCode()
★★★★★★★★★★★★★★★★★」person2.hashCode()
결가가달 달달가가크
지도는 다른 linked Lists에 있는 사람들로 끝날 수 있습니다.
이것은 HashMap의 논리에 위배됩니다.
HashMap에는 동일한 키를 여러 개 사용할 수 없습니다.
, 현재 하고 있습니다.로는 「 」가 입니다.hashCode()
오브젝트 클래스「 」를 한 .equals()
츠미야
에 우선시하지 안 됩니다.hashCode()
「 「 」 」 method 。equals
★★★★★★ 。
이제 그걸 고쳐보자.보다 우선시하자.hashCode()
equals()
즉 「」를 고려합니다.age, name
public class Person {
private Integer age;
private String name;
..getters, setters, constructors
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
다시 한번 해시맵에 키를 저장해 보겠습니다.
Map<Person, String> map = new HashMap();
map.put(person1, "1");
map.put(person2, "2");
person1.hashCode()
★★★★★★★★★★★★★★★★★」person2.hashCode()
확실히 똑같을 거예요.들어 0.0으로 하자.
HashMap은 버킷0으로 이동하고 LinkedList에서는 person1을 값 "1"의 키로 저장합니다.두 번째 입력의 경우 HashMap은 충분히 인텔리전트하며 버킷0으로 이동하여 값 "2"의 person2 키를 저장하면 동일한 키가 이미 존재하는 것을 알 수 있습니다.따라서 이전 키를 덮어씁니다.따라서 최종적으로 HashMap에는 person2 키만 존재합니다.
이제 동일한 키를 여러 개 사용할 수 없다는 해시 맵의 규칙에 맞게 되었습니다.
간단히 말해 오브젝트의 equals-method는 참조가 동일한지 여부를 확인합니다.이 경우 속성이 동일한 경우에도 클래스의 두 인스턴스가 의미적으로 동일한 경우가 있습니다.이것은 예를 들어 HashMap 및 Set와 같이 equals 및 해시 코드를 사용하는 컨테이너에 개체를 넣을 때 중요합니다.예를 들어 다음과 같은 수업이 있다고 합시다.
public class Foo {
String id;
String whatevs;
Foo(String id, String whatevs) {
this.id = id;
this.whatevs = whatevs;
}
}
동일한 ID로 두 개의 인스턴스를 만듭니다.
Foo a = new Foo("id", "something");
Foo b = new Foo("id", "something else");
우선시하지 않으면 다음과 같은 결과를 얻을 수 있습니다.
- a.disc(b)는 2개의 다른 인스턴스이기 때문에 false입니다.
- a.disc(a)는 같은 예이기 때문에 true이다.
- 같은 인스턴스이기 때문에 b.disc(b)는 true입니다.
맞습니까?그게 네가 원하는 거라면 그럴지도 모르지그러나 동일한 ID를 가진 개체가 두 개의 다른 인스턴스인지 여부에 관계없이 동일한 개체로 지정된다고 가정합니다.등호(및 해시 코드)는 덮어씁니다.
public class Foo {
String id;
String whatevs;
Foo(String id, String whatevs) {
this.id = id;
this.whatevs = whatevs;
}
@Override
public boolean equals(Object other) {
if (other instanceof Foo) {
return ((Foo)other).id.equals(this.id);
}
}
@Override
public int hashCode() {
return this.id.hashCode();
}
}
equals와 hashcode의 실장에 대해서는 Guava의 도우미 메서드를 사용하는 것을 추천합니다.
개념을 아주 간단한 말로 설명하겠습니다.
우선 넓은 관점에서 보면 컬렉션이 있습니다.해시맵은 컬렉션의 데이터 구조 중 하나입니다.
해시맵과 해시코드 방식을 모두 덮어쓸 필요가 있는 이유를 이해하려면 먼저 해시맵의 내용과 기능을 이해해야 합니다.
해시맵은 데이터의 주요 값 쌍을 배열 방식으로 저장하는 데이터 구조입니다.a[]라고 합니다.여기서 'a'의 각 요소는 키 값 쌍입니다.
또, 상기 배열내의 각 인덱스는 링크 리스트 할 수 있기 때문에, 1개의 인덱스에 복수의 값을 가질 수 있다.
해시맵이 사용되는 이유는 무엇입니까?
대규모 어레이를 검색해야 할 경우 각각의 어레이를 검색하는 것이 효율적이지 않은지 확인합니다.따라서 어떤 해시 기술을 통해 어레이를 사전에 처리하고 그 논리에 따라 요소를 그룹화할 수 있는지, 예를 들어 다음과 같이 설명합니다.해싱
EG: 어레이 1,2,3,4,5,6,7,8,9,10,11이 있고,11이 그룹화되도록 해시함수 mod 10을 적용합니다.따라서 이전 어레이에서 11개를 검색해야 하는 경우 전체 어레이를 반복해야 하지만 그룹화할 때는 반복 범위를 제한하여 속도가 향상됩니다.위의 모든 정보를 저장하는 데 사용되는 데이터 구조는 단순성을 위해 2D 어레이로 간주할 수 있습니다.
위의 해시맵과는 별도로 중복이 추가되지 않음을 나타냅니다.그리고 이것이 우리가 등호나 해시 코드를 덮어써야 하는 주된 이유입니다.
따라서 해시맵의 내부 작업을 설명하는 경우 해시맵이 어떤 메서드를 가지고 있는지, 그리고 위에서 설명한 규칙을 어떻게 따르고 있는지 알아내야 합니다.
따라서 해시맵에는 put(K,V)라고 불리는 메서드가 있으며 해시맵에 따르면 어레이를 효율적으로 배포하고 중복을 추가하지 않는 위의 규칙을 따라야 합니다.
따라서 지정된 키의 해시 코드를 생성하여 값이 들어가는 인덱스를 결정합니다.이 인덱스에 아무것도 존재하지 않으면 새로운 값이 저기에 추가되고, 이미 저기에 어떤 것이 존재한다면 새로운 값이 해당 인덱스의 링크 리스트가 끝난 후에 추가되어야 합니다.단, dup은 기억나지 않습니다.라이선스는 해시맵의 원하는 동작에 따라 추가해야 합니다.따라서 두 개의 정수 객체 aa=11,bb=11이 있다고 가정합니다.
오브젝트 클래스에서 파생된 모든 오브젝트로서 두 오브젝트를 비교하는 기본 구현은 오브젝트 내부의 값이 아닌 참조를 비교하는 것입니다.따라서 위의 경우 의미적으로는 동일하지만 동등성 테스트에 실패하며 해시 코드와 값이 동일한2개의 오브젝트가 존재하여 중복이 생성될 가능성이 있습니다.오버라이드하면 중복되는 것을 피할 수 있습니다.자세한 작업도 참조할 수 있습니다.
import java.util.HashMap;
public class Employee {
String name;
String mobile;
public Employee(String name,String mobile) {
this.name = name;
this.mobile = mobile;
}
@Override
public int hashCode() {
System.out.println("calling hascode method of Employee");
String str = this.name;
int sum = 0;
for (int i = 0; i < str.length(); i++) {
sum = sum + str.charAt(i);
}
return sum;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
System.out.println("calling equals method of Employee");
Employee emp = (Employee) obj;
if (this.mobile.equalsIgnoreCase(emp.mobile)) {
System.out.println("returning true");
return true;
} else {
System.out.println("returning false");
return false;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Employee emp = new Employee("abc", "hhh");
Employee emp2 = new Employee("abc", "hhh");
HashMap<Employee, Employee> h = new HashMap<>();
//for (int i = 0; i < 5; i++) {
h.put(emp, emp);
h.put(emp2, emp2);
//}
System.out.println("----------------");
System.out.println("size of hashmap: "+h.size());
}
}
Java는 다음과 같은 규칙을 설정합니다.
"Object class equals 메서드를 사용하여 두 객체가 동일한 경우 해시 코드 메서드는 이 두 객체에 대해 동일한 값을 제공해야 합니다.
그래서, 우리 반에서 우리가 우리보다 우선한다면equals()
는 우선시해야 .hashcode()
이 규칙을 따르는 방법도 있습니다.가지 방법 모두 " " " 입니다.equals()
★★★★★★★★★★★★★★★★★」hashcode()
는 에 Hashtable
예를 들어, 값을 키와 값의 쌍으로 저장합니다., 에 있는 것이 다른 한쪽이 덮어쓰게 될 가능성이 있습니다.Hashtable
그런 오브젝트를 키로 사용하면 우리가 원하는 대로 작동하지 않을 수 있습니다.
hashCode()
:
코드 방식이 에 아무도 일어나지 .hashCode
오브젝트 클래스로서 각 오브젝트에 대해서.
equals()
:
, equals 메서드만 .a.equals(b)
는 "true", "true"를합니다.hashCode
a, b, b, b, b, b는 동일해야 합니다.a, b, n, n, n, n을 에 발생하지 않습니다.hashCode
★★★★★★ 。
★★★★★★hashCode()
class는 새 개체 를 반환합니다.hashCode
각 오브젝트에 대해.
컬렉션에서 해야 할 두 개체를 모두 .equals()
★★★★★★★★★★★★★★★★★」hashCode()
.
재정의하지 않으면 개체에서 기본 함의가 사용되기 때문입니다.
인스턴스 등호도 및 하스코드 값은 일반적으로 객체를 구성하는 요소에 대한 지식이 필요하기 때문에 일반적으로 클래스에서 명확한 의미를 가지려면 이러한 값을 재정의해야 합니다.
HashMap, Hashtable 등의 컬렉션에서 자체 클래스 오브젝트를 키로 사용하려면 수집 내부 작업에 대한 인식으로 두 메서드(hashCode() 및 equals())를 모두 덮어써야 합니다.그렇지 않으면 우리가 예상하지 못한 잘못된 결과로 이어질 수 있습니다.
@Lombo의 답변에 추가
언제 등호()를 덮어쓸 필요가 있습니까?
개체의 equals() 기본 구현은 다음과 같습니다.
public boolean equals(Object obj) {
return (this == obj);
}
즉, 두 개체가 동일한 메모리 주소를 가진 경우에만 동일한 것으로 간주되며, 개체와 개체를 비교하는 경우에만 해당됩니다.
그러나 두 개체가 하나 이상의 속성에 대해 동일한 값을 갖는 경우 동일한 것으로 간주할 수 있습니다(@Lombo의 답변 예 참조).
에, 「 」를 덮어씁니다.equals()
이런 상황에서 당신은 평등을 위한 당신만의 조건을 제시할 것이다.
equals()를 정상적으로 구현하여 정상적으로 동작하고 있습니다.그럼 왜 hash Code()도 덮어쓰라고 하는 걸까요?
사용자 정의 클래스에서 "해시" 기반 컬렉션을 사용하지 않는 한 문제 없습니다.하지만 미래에는 이 시스템을 사용하는 것이 좋을지도 모릅니다.HashMap
★★★★★★★★★★★★★★★★★」HashSet
않으면override
hashCode()를 "올바르게 구현"하면 이러한 해시 기반 컬렉션은 의도한 대로 작동하지 않습니다.
[Override only equals](@Lombo의 답변에 추가)
myMap.put(first,someValue)
myMap.contains(second); --> But it should be the same since the key are the same.But returns false!!! How?
은 "HashMap" hashCode"의가 "HashCode"인지 합니다.second
is is is is is와 first
값이 같은 경우에만 동일한 버킷 내의 동일성을 확인합니다.
단, 여기서 hashCode는 이들2개의 오브젝트에 대해 다릅니다(메모리 주소가 디폴트 실장과는 다르기 때문입니다.그러므로 그것은 평등을 확인하는 것조차 신경 쓰지 않을 것이다.
오버라이드된 equals() 메서드에 브레이크포인트가 있는 경우 해시코드가 다르면 브레이크포인트가 끼어들지 않습니다. contains()
hashCode()
두 에만 당신의 이름을 '자신의 것', '자신의 것', '자신의 것'이라고 .equals()
★★★★★★ 。
HashMap에서 모든 버킷의 동일성을 검사하도록 할 수 없는 이유는 무엇입니까?따라서 hash Code()를 덮어쓸 필요가 없습니다.
그러면 해시 기반 컬렉션의 요점이 누락됩니다.다음 사항을 고려하십시오.
Your hashCode() implementation : intObject%9.
다음은 버킷 형식으로 저장된 키입니다.
Bucket 1 : 1,10,19,... (in thousands)
Bucket 2 : 2,20,29...
Bucket 3 : 3,21,30,...
...
지도에 10번 키가 있는지 알고 싶으시다고요?모든 버킷을 검색하시겠습니까?아니면 한 버킷만 검색하시겠습니까?
hashCode에 근거하여 10이 존재하는 경우 버킷1에 존재해야 함을 식별합니다.따라서 버킷1만 검색됩니다!!
class A {
int i;
// Hashing Algorithm
if even number return 0 else return 1
// Equals Algorithm,
if i = this.i return true else false
}
- put '는 put'key' 'value'를 사용하여 합니다.
hashCode()
equals()
메서드를 사용하여 버킷에 값이 이미 있는지 여부를 확인합니다.됩니다. - 는 get'key')를 사용합니다.
hashCode()
엔트리를 검색하여 " (버킷을 찾습니다.equals()
.
둘 다 덮어쓰면
지도 <A>
Map.Entry 1 --> 1,3,5,...
Map.Entry 2 --> 2,4,6,...
등호가 재정의되지 않은 경우
지도 <A>
Map.Entry 1 --> 1,3,5,...,1,3,5,... // Duplicate values as equals not overridden
Map.Entry 2 --> 2,4,6,...,2,4,..
hashCode가 재정의되지 않은 경우
지도 <A>
Map.Entry 1 --> 1
Map.Entry 2 --> 2
Map.Entry 3 --> 3
Map.Entry 4 --> 1
Map.Entry 5 --> 2
Map.Entry 6 --> 3 // Same values are Stored in different hasCodes violates Contract 1
So on...
해시 코드 등가 계약
- 동일한 메서드에 따라 동일한 두 키가 동일한 해시 코드를 생성해야 합니다.
- 동일한 hashCode를 생성하는 2개의 키가 같을 필요는 없습니다(위의 예에서는 모든 짝수가 동일한 해시 코드를 생성합니다).
1) 일반적인 실수는 아래 예시와 같습니다.
public class Car {
private String color;
public Car(String color) {
this.color = color;
}
public boolean equals(Object obj) {
if(obj==null) return false;
if (!(obj instanceof Car))
return false;
if (obj == this)
return true;
return this.color.equals(((Car) obj).color);
}
public static void main(String[] args) {
Car a1 = new Car("green");
Car a2 = new Car("red");
//hashMap stores Car type and its quantity
HashMap<Car, Integer> m = new HashMap<Car, Integer>();
m.put(a1, 10);
m.put(a2, 20);
System.out.println(m.get(new Car("green")));
}
}
녹색 차를 찾을 수 없습니다.
2. hash Code()에 의한 문제
메서드로 인해 합니다.hashCode()
의 계약.간의 계약서equals()
★★★★★★★★★★★★★★★★★」hashCode()
말합니다
- 두 개체가 동일한 경우 동일한 해시 코드를 가져야 합니다.
두 개체의 해시 코드가 동일한 경우 같거나 같지 않을 수 있습니다.
public int hashCode(){ return this.color.hashCode(); }
값 개체를 사용할 때 유용합니다.다음은 Portland Pattern Repository에서 발췌한 것입니다.
값 객체의 예로는 숫자, 날짜, 돈, 문자열 등이 있습니다.보통, 그것들은 꽤 널리 사용되는 작은 물체들이다.그들의 정체성은 그들의 객체 정체성보다는 그들의 상태에 기초합니다.이렇게 하면 동일한 개념 값 개체의 복사본을 여러 개 가질 수 있습니다.
따라서 1998년 1월 16일을 나타내는 오브젝트의 복사본을 여러 개 가질 수 있습니다.이 복사본들 중 어느 것이든 서로 동일할 것이다.이와 같은 작은 객체의 경우 날짜를 나타내는 단일 객체에 의존하는 것보다 새 객체를 만들고 이동하는 것이 더 쉬운 경우가 많습니다.
값 개체는 Java(또는 Smalltalk의 경우 =)의 경우 항상 .value()를 재정의해야 합니다.(.hashCode()도 덮어쓰는 것을 잊지 마십시오).
다른 2개의 (B) (C)를 집약하는 클래스(A)가 있고 (A)의 인스턴스를 해시 테이블 내에 저장해야 한다고 가정합니다.디폴트 실장에서는 인스턴스를 구별할 수 있을 뿐 (B)와 (C)에서는 구분할 수 없습니다.따라서 A의 두 인스턴스는 같을 수 있지만 기본값으로는 두 인스턴스를 올바르게 비교할 수 없습니다.
양동이에 모두 검은색으로 된 공 수집을 고려해 보십시오.당신의 일은 그 공을 다음과 같이 색칠하여 적절한 게임에 사용하는 것입니다.
테니스용 - 노란색, 빨간색.크리켓용 - 흰색
이제 양동이는 노란색, 빨간색, 흰색의 세 가지 색깔의 공을 가지고 있다.색칠을 했으니 어떤 색이 어떤 게임인지 알 수 있죠?
공을 색칠하기 - 해싱.게임을 위한 공 고르기 - 동등합니다.
색칠을 했는데 누군가 크리켓이나 테니스에서 공을 선택한다면 그들은 색칠에 신경 쓰지 않을 것이다!!!
, "hashCode"를 했습니다.myMap.put(first,someValue)
「hash Code」 「hash Code」 「hash Code」 「hash Code」 「hash Code 」 나서, 이 전화했을 때.myMap.put(first,someOtherValue)
예: " )는 다음과 같습니다.
는 두 번째 라고 생각합니다.myMap
'두 번째는 '두 번째 합니다.myMap.put(second,someOtherValue)
메서드와 해시코드는 오브젝트클래스에 정의되어 있습니다.기본적으로는 equals 메서드가 true를 반환하면 시스템은 더 나아가 해시 코드 값을 확인합니다.두 개체의 해시 코드도 동일한 경우 개체는 동일한 것으로 간주됩니다.따라서 equals 메서드만 덮어쓸 경우 overrided equals 메서드는 2개의 오브젝트가 동일함을 나타내지만 시스템 정의 해시 코드는 2개의 오브젝트가 동일함을 나타내지 않을 수 있습니다.따라서 해시 코드도 덮어쓸 필요가 있습니다.
Java의 Equals 및 Hashcode 메서드
java.lang 메서드입니다.모든 클래스의 슈퍼 클래스인 오브젝트클래스(커스텀클래스 및 Java API에 정의되어 있는 기타 클래스).
구현:
public boolean equals(개체 obj)
public int hash Code()
public boolean equals(개체 obj)
이 메서드는 x와 y가 참조하는 두 개체가 동일한 개체를 참조하는지 여부를 확인합니다.x == y인지 확인합니다.
이것은 반사적입니다.기준값 x에 대해 x.equals(x)는 true를 반환합니다.
이 값은 대칭입니다.기준값 x와 y에 대해 y.equals(x)가 true를 반환하는 경우에만 x.equals(y)가 true를 반환해야 합니다.
이것은 추이적입니다.기준값 x, y 및 z에 대해 x.equals(y)가 true를 반환하고 y.equals(z)가 true를 반환하면 x.equals(z)는 true를 반환해야 합니다.
일관성이 있습니다.x 와 y 의 참조치에 대해서, x.equals(y) 의 복수 호출은, 오브젝트의 등가 비교에 사용되는 정보가 변경되지 않는 한, 일관되게 true 를 반환하거나 false 를 반환합니다.
null이 아닌 참조값 x의 경우 x.equals(null)는 false를 반환해야 합니다.
public int hash Code()
이 메서드는 이 메서드가 호출된 개체의 해시 코드 값을 반환합니다.이 메서드는 해시 코드 값을 정수로 반환하며 해시 테이블, 해시 맵, 해시 세트 등의 해시 기반 수집 클래스를 위해 지원됩니다.이 메서드는 equal 메서드를 덮어쓰는 모든 클래스에서 덮어써야 합니다.
hashCode의 일반 계약은 다음과 같습니다.
Java 응용 프로그램 실행 중에 동일한 개체에서 여러 번 호출될 때마다 hashCode 메서드는 동일한 정수를 일관되게 반환해야 합니다.단, 동일한 비교에서 사용되는 정보는 변경되지 않습니다.
이 정수는 응용 프로그램 실행 간에 일관성을 유지할 필요가 없습니다.
2개의 객체가 equals(Object) 메서드에 따라 동일한 경우 2개의 객체 각각에서 hashCode 메서드를 호출하면 동일한 정수 결과가 생성되어야 합니다.
2개의 오브젝트가 equals(java.lang)에 따라 동일하지 않은 경우에는 필요하지 않습니다.Object) 메서드를 호출하면 두 오브젝트 각각에서 hashCode 메서드를 호출하여 고유한 정수 결과를 생성해야 합니다.단, 프로그래머는 불평등한 오브젝트에 대해 별개의 정수 결과를 생성하면 해시 테이블의 성능이 향상될 수 있음을 알아야 합니다.
동일한 개체는 동일한 해시 코드를 생성해야 합니다. 단, 동일한 개체는 고유한 해시 코드를 생성할 필요가 없습니다.
자원:
「」를 무효로 equals()
andhashcode()
하지 않는 한 가 없습니다.HashSet
저보다 앞선 분들이 여러 번 명확하게 문서화된 이론을 설명하셨는데, 저는 아주 간단한 예를 들려고 왔습니다.
다음과 같은 클래스를 고려합니다.equals()
커스터마이즈된 것을 의미할 필요가 있다:-
public class Rishav {
private String rshv;
public Rishav(String rshv) {
this.rshv = rshv;
}
/**
* @return the rshv
*/
public String getRshv() {
return rshv;
}
/**
* @param rshv the rshv to set
*/
public void setRshv(String rshv) {
this.rshv = rshv;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Rishav) {
obj = (Rishav) obj;
if (this.rshv.equals(((Rishav) obj).getRshv())) {
return true;
} else {
return false;
}
} else {
return false;
}
}
@Override
public int hashCode() {
return rshv.hashCode();
}
}
이 메인 클래스를 생각해 보겠습니다.-
import java.util.HashSet;
import java.util.Set;
public class TestRishav {
public static void main(String[] args) {
Rishav rA = new Rishav("rishav");
Rishav rB = new Rishav("rishav");
System.out.println(rA.equals(rB));
System.out.println("-----------------------------------");
Set<Rishav> hashed = new HashSet<>();
hashed.add(rA);
System.out.println(hashed.contains(rB));
System.out.println("-----------------------------------");
hashed.add(rB);
System.out.println(hashed.size());
}
}
이것에 의해, 다음의 출력이 출력됩니다.
true
-----------------------------------
true
-----------------------------------
1
결과에 만족합니다.하지만 내가 무시하지 않았다면hashCode()
의 오브젝트로서 악몽을 일으킵니다.Rishav
같은 멤버의 콘텐츠를 가진 경우,hashCode
디폴트 동작에 의해 생성된 것과 달리,는 다음과 같이 출력됩니다.-
true
-----------------------------------
false
-----------------------------------
2
다음 예시에서 Person 클래스의 equals 또는 hashcode에 대한 오버라이드를 코멘트 아웃하면 이 코드는 Tom의 주문을 조회하지 못합니다.기본 해시 코드 구현을 사용하면 해시 테이블 검색에서 오류가 발생할 수 있습니다.
아래에 있는 것은 사람별 주문을 불러오는 간단한 코드입니다.사용자가 해시 테이블에서 키로 사용되고 있습니다.
public class Person {
String name;
int age;
String socialSecurityNumber;
public Person(String name, int age, String socialSecurityNumber) {
this.name = name;
this.age = age;
this.socialSecurityNumber = socialSecurityNumber;
}
@Override
public boolean equals(Object p) {
//Person is same if social security number is same
if ((p instanceof Person) && this.socialSecurityNumber.equals(((Person) p).socialSecurityNumber)) {
return true;
} else {
return false;
}
}
@Override
public int hashCode() { //I am using a hashing function in String.java instead of writing my own.
return socialSecurityNumber.hashCode();
}
}
public class Order {
String[] items;
public void insertOrder(String[] items)
{
this.items=items;
}
}
import java.util.Hashtable;
public class Main {
public static void main(String[] args) {
Person p1=new Person("Tom",32,"548-56-4412");
Person p2=new Person("Jerry",60,"456-74-4125");
Person p3=new Person("Sherry",38,"418-55-1235");
Order order1=new Order();
order1.insertOrder(new String[]{"mouse","car charger"});
Order order2=new Order();
order2.insertOrder(new String[]{"Multi vitamin"});
Order order3=new Order();
order3.insertOrder(new String[]{"handbag", "iPod"});
Hashtable<Person,Order> hashtable=new Hashtable<Person,Order>();
hashtable.put(p1,order1);
hashtable.put(p2,order2);
hashtable.put(p3,order3);
//The line below will fail if Person class does not override hashCode()
Order tomOrder= hashtable.get(new Person("Tom", 32, "548-56-4412"));
for(String item:tomOrder.items)
{
System.out.println(item);
}
}
}
hashCode()
method는 지정된 객체에 대한 고유한 정수를 얻기 위해 사용됩니다.이 정수는 이 개체를 저장해야 하는 버킷 위치를 결정하는 데 사용됩니다.HashTable
,HashMap
같은 데이터 구조입니다.디폴트로는 오브젝트hashCode()
method는 오브젝트가 저장되어 있는 메모리주소의 정수 표현을 반환합니다.
그hashCode()
오브젝트의 메서드는 우리가 그것들을 삽입할 때 사용됩니다.HashTable
,HashMap
또는HashSet
자세한 것은 이쪽HashTables
를 참조해 주세요.
지도 데이터 구조에 엔트리를 삽입하려면 키와 값이 모두 필요합니다.키와 값이 모두 사용자 정의 데이터 유형인 경우hashCode()
오브젝트의 내부 저장 장소를 결정합니다.맵에서 오브젝트를 검색해야 할 경우 키의 해시코드에 따라 오브젝트의 검색처가 결정됩니다.
해시 코드는 특정 영역(또는 목록, 버킷 등)을 내부적으로만 가리킵니다.다른 키 객체가 동일한 해시 코드를 가질 수 있기 때문에 해시 코드 자체는 올바른 키를 찾을 수 있다는 보장은 없습니다.그HashTable
그런 다음 이 영역(같은 해시 코드를 가진 모든 키)을 반복하고 키의equals()
적절한 키를 찾을 수 있습니다.올바른 키가 발견되면 해당 키에 대해 저장된 개체가 반환됩니다.
보다시피, 그 조합은hashCode()
그리고.equals()
저장 및 검색 시 메서드가 사용됩니다.HashTable
.
주의:
생성할 개체의 동일한 속성을 항상 사용합니다.
hashCode()
그리고.equals()
둘 다요 우리 사건처럼 직원 ID를 사용했어요equals()
일관성이 있어야 합니다(개체가 변경되지 않은 경우 계속 같은 값을 반환해야 합니다).언제든지
a.equals(b)
,그리고나서a.hashCode()
와 같아야 합니다.b.hashCode()
.하나를 재정의하면 다른 하나를 재정의해야 합니다.
http://parameshk.blogspot.in/2014/10/examples-of-comparable-comporator.html
문자열 클래스와 래퍼 클래스의 실장은 다릅니다.equals()
그리고.hashCode()
메서드가 오브젝트 클래스보다 커집니다.오브젝트 클래스의 equals() 메서드는 내용이 아닌 오브젝트의 참조를 비교합니다.오브젝트 클래스의 hashCode() 메서드는 내용이 동일한지 여부에 관계없이 모든 오브젝트에 대해 고유한 해시 코드를 반환합니다.
Map 컬렉션을 사용하고 키가 지속 유형, StringBuffer/빌더 유형인 경우 문제가 발생합니다.string 클래스와 달리 equals()와 hashCode()는 덮어쓰지 않기 때문에 equals()는 두 개의 다른 개체를 비교할 때 false를 반환합니다.그러면 hashMap이 동일한 콘텐츠키를 저장합니다.동일한 콘텐츠 키를 저장하는 것은 Map에서 중복 키를 허용하지 않으므로 Map 규칙을 위반하는 것입니다.따라서 클래스의 hashCode() 메서드뿐만 아니라 equals() 메서드를 덮어쓰고 구현(IDE는 이러한 메서드를 생성할 수 있음)을 제공하여 String의 equals() 및 hashCode()와 동일하게 동작하고 동일한 콘텐츠키를 방지합니다.
equals()는 해시 코드에 따라 동작하기 때문에 equals()와 함께 hashCode() 메서드를 덮어써야 합니다.
또한 hashCode() 메서드를 equals()와 함께 덮어쓰는 것은 equals()-hashCode() 계약을 유지하는 데 도움이 됩니다. "두 개체가 같으면 두 개체는 동일한 해시 코드를 가져야 합니다."
hashCode()의 커스텀 실장은 언제 작성해야 합니까?
아시다시피 HashMap의 내부 작업은 Hashing의 원리로 이루어집니다.엔트리 세트가 저장되는 특정 버킷이 있습니다.hashCode() 실장은 필요에 따라 커스터마이즈하여 동일한 카테고리의 오브젝트를 같은 인덱스에 저장할 수 있습니다.이 경우 값을 Map 컬렉션에 저장합니다.put(k,v)
put()의 내부 실장은 다음과 같습니다.
put(k, v){
hash(k);
index=hash & (n-1);
}
즉, 인덱스를 생성하고 인덱스는 특정 키 객체의 해시 코드를 기반으로 생성됩니다.따라서 동일한 해시 코드 엔트리 세트가 동일한 버킷 또는 인덱스에 저장되므로 이 메서드에 따라 해시 코드를 생성하도록 하십시오.
바로 그거야!
IMHO는 규칙에 따라 - 두 개체가 동일한 경우 동일한 해시를 가져야 합니다. 즉, 동일한 개체는 동일한 해시 값을 생성해야 합니다.
위의 경우 개체의 기본 equals()는 주소를 비교하는 ==이며, hashCode()는 주소를 정수(실제 주소의 경우)로 반환합니다. 이는 별개의 개체에 대해 다시 구별됩니다.
해시 기반 컬렉션에서 커스텀오브젝트를 사용해야 할 경우 equals()와 hashCode()를 모두 덮어쓸 필요가 있습니다.예를 들어, 종업원 객체의 HashSet을 유지하려면 보다 강력한 HashCode를 사용하지 않고 동일한 HashCode를 사용하는 경우, 이는 연령을 Hash(Hash)로 사용할 때 발생할 수 있습니다.에서는, 종업원 ID 가 될 수 있는 일의의 값을 사용할 필요가 있습니다.
중복된 오브젝트를 체크하기 위해서는 커스텀 등가 및 해시 코드가 필요합니다.
해시코드는 항상 숫자를 반환하므로 알파벳 키가 아닌 숫자를 사용하여 개체를 검색하는 것이 항상 빠릅니다.어떻게 될까요?다른 개체에서 이미 사용 가능한 값을 전달하여 새 개체를 생성했다고 가정합니다.전달된 값이 동일하기 때문에 새 개체는 다른 개체와 동일한 해시 값을 반환합니다.동일한 해시 값이 반환되면 JVM은 매번 동일한 메모리 주소로 이동합니다.같은 해시 값에 여러 개체가 존재하는 경우 올바른 개체를 식별하기 위해 equals() 메서드를 사용합니다.
커스텀 오브젝트를 Map에서 키로 저장 및 취득하는 경우 커스텀오브젝트에서는 항상 equals와 hashCode를 덮어써야 합니다.예:
Person p1 = new Person("A",23);
Person p2 = new Person("A",23);
HashMap map = new HashMap();
map.put(p1,"value 1");
map.put(p2,"value 2");
여기서 p1과 p2는 하나의 오브젝트로서만 간주하고,map
크기가 같기 때문에 1이 됩니다.
public class Employee {
private int empId;
private String empName;
public Employee(int empId, String empName) {
super();
this.empId = empId;
this.empName = empName;
}
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
@Override
public String toString() {
return "Employee [empId=" + empId + ", empName=" + empName + "]";
}
@Override
public int hashCode() {
return empId + empName.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(this instanceof Employee)) {
return false;
}
Employee emp = (Employee) obj;
return this.getEmpId() == emp.getEmpId() && this.getEmpName().equals(emp.getEmpName());
}
}
테스트 클래스
public class Test {
public static void main(String[] args) {
Employee emp1 = new Employee(101,"Manash");
Employee emp2 = new Employee(101,"Manash");
Employee emp3 = new Employee(103,"Ranjan");
System.out.println(emp1.hashCode());
System.out.println(emp2.hashCode());
System.out.println(emp1.equals(emp2));
System.out.println(emp1.equals(emp3));
}
}
Object Class equals(Object obj)에서는 주소 비교를 위해 사용됩니다.이 때문에 테스트클래스에서 2개의 오브젝트를 비교하면 메서드 giving false가 되지만 해시 코드()를 덮어쓰면 콘텐츠를 비교하여 적절한 결과를 얻을 수 있습니다.
두 메서드는 모두 오브젝트클래스에 정의되어 있습니다.그리고 둘 다 가장 간단한 구현에 있습니다.따라서 이러한 메서드에 구현을 추가해야 할 경우 클래스에서 덮어쓰기를 사용할 수 있습니다.
오브젝트의 Ex: equals() 메서드의 경우 참조상의 동일성만 체크합니다.따라서 String 클래스에서와 마찬가지로 상태를 비교할 필요가 있는 경우 해당 상태를 덮어쓸 수 있습니다.
Equals/Hashcode 계약 테스트에 대한 이 답변에는 아무런 언급이 없습니다.
EqualsVerifier 라이브러리는 매우 유용하고 포괄적이라고 생각합니다.사용법도 매우 편리합니다.
또, 건축equals()
그리고.hashCode()
처음부터 방법은 많은 상용 코드를 수반합니다.Apache Commons Lang 라이브러리는 EqualsBuilder 및 HashCodeBuilder 클래스를 제공합니다.이러한 클래스에서는, 실장이 큰폭으로 심플화됩니다.equals()
그리고.hashCode()
복잡한 클래스의 메서드.
여담이지만, 이 문제를 덮어쓰는 것을 고려해볼 가치가 있습니다.toString()
디버깅을 지원하는 메서드입니다.Apache Commons Lang 라이브러리는 이를 지원하기 위해 ToStringBuilder 클래스를 제공합니다.
언급URL : https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java
'programing' 카테고리의 다른 글
C 프로그래밍용 REP가 있습니까? (0) | 2022.08.01 |
---|---|
Android, 문자열에서 리소스 ID를 가져오고 있습니까? (0) | 2022.08.01 |
antd vue의 a-table 행에 click listener를 추가하는 방법 (0) | 2022.08.01 |
사용자가 Nuxt/Vuex/Vue를 사용하여 브라우저의 Back 버튼을 통해 라우팅할 수 있는지 여부를 검출합니다. (0) | 2022.08.01 |
개체(...)가 Vuex 스토어의 함수가 아닙니다. (0) | 2022.08.01 |