equals () 와hashcode () 에 대해 당신이 알아야 할 모든 것
1. equal()과 ==의 차이는 무엇입니까?
equals () 방법을 이해하려면 반드시 ==부터 말해야 한다.
==의 역할은 매우 간단하다. 바로 두 대상의 주소가 같은지 아닌지를 판단하는 것이다(기본 데이터 유형은 값을 비교하고 인용 데이터 유형은 주소를 비교한다).
그럼 equal () 방법은요?이것은 Object 객체의 한 방법입니다. 모든 클래스가 Object에서 상속되기 때문에 모든 클래스에 equal () 방법이 있습니다.Object의 원본 코드에서 equal () 방법이 어떻게 생겼는지 볼 수 있습니다.
public boolean equals(Object obj) {
return (this == obj);
}
너는 이것이 바로 ==과 같지 않다고 생각할 것이다??네, 확실히 똑같습니다. 그런데 왜 equals () 방법을 더 만들어야 합니까?사실 equals () 방법은 자바가 우리에게 다시 쓰라고 제공하는 것이다.일반적으로 우리는 equals () 방법을 사용하여 두 대상의 내용이 같은지 비교하는데 다음과 같은 예를 볼 수 있다.
/**
* @Author shenghai
* @Date 4/19 19:03
*/
public class test {
public static void main(String[] args) {
Person p1 = new Person("abc", 111);
Person p2 = new Person("abc", 111);
System.out.printf("p1.equals(p2) : %s
", p1.equals(p2));
System.out.printf("p1==p2 : %s
", p1==p2);
}
private static class Person {
int age;
String name;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj){
if(obj == null) {
return false;
}
if(this == obj) {
return true;
}
//
if(this.getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return name.equals(person.name) && age==person.age; // name equals String
}
}
}
/**
* :
* p1.equals(p2) : true
* p1==p2 : false
*/
이를 통해 알 수 있듯이 Person 대상에서 우리는 equals() 방법을 다시 썼고 주요 논리는 마지막 문장에서 Person류의 필드
name
와 age
가 모두 같은지 판단했다.이렇게 해서 우리는 새로운 규칙을 사용하여 두 Person 대상의 주소가 같은지 아닌지를 판단하는 것이지 원시적인 ==을 사용하여 두 Person 대상의 주소가 같은지 판단하는 것이 아니다.2.hashCode()의 역할
equals ()와 마찬가지로 hashCode () 도 Object 클래스의 한 방법으로, 이것은 native 방법 (즉 JNI 방법, Java Native Interface, 원본 코드는 C로 쓴 것) 이다.
public native int hashCode();
hashCode () 의 역할은 해시 코드를 가져오는 것입니다. 이것은 실제적으로 int 정수를 되돌려줍니다.이 해시 코드의 역할은 그 대상이 해시 표에 있는 위치를 확정하는 것이다.따라서hashCode()는 해시 테이블에서만 사용할 수 있고 다른 상황에서는 쓸모가 없다.이곳의 해시표는 해시맵, 해시셋, 해시테이블 등을 포함한다.
그럼 왜 해시코드가 있는 거죠?
조금 간단한 해시셋을 예로 들면, 대상을 해시셋에 넣을 때, 해시셋은 대상의hashCode 값을 먼저 계산해서 대상이 들어간 위치를 얻고, 이 위치의 다른 이미 들어간 대상의hashCode 값과 비교할 때, 이때는 이퀄스 () 방법을 사용해서hashCode와 같은 대상이 정말 같은지 확인한다. (즉 우리가 다시 쓴 이퀄스 () 방법으로 판단한다.만약 "정말 같다"면, HashSet은 작업에 성공하지 못하게 할 것입니다.만약 같지 않다면 해시가 충돌하여 이 대상을 해시를 다른 위치로 옮길 것이다.
3. hashCode()와 equals()의 관계
여기에는 두 가지 상황으로 나누어 토론해야 한다.
3.1 해시 테이블에서 사용하지 않음
여기서 말한 것은 우리가 Obj 대상이 있다고 가정하지만 HashSet,Hashtable,HashMap 등 본질이 산목록의 데이터 구조에서 이 대상을 사용하지 않았다는 것이다.
그럼, 이런 상황에서 당신이 어떻게 equals () 방법을 다시 쓰든hashCode () 방법과 아무런 관계가 없습니다!!
3.2 해시 테이블에서 사용
그러나 만약에 우리가 해시표를 사용한다면 우리는 두 대상이 같다면 그것들의hashCode값은 반드시 같다는 것을 보증해야 한다. (여기서 같은 것은 equals()를 통해 두 대상을 비교할 때true로 돌아가는 것을 가리킨다.)
따라서 이 경우 두 대상이 동일한지 판단하려면 equals() 방법 외에 hashCode() 방법도 다시 써야 한다.
만약에 우리가 equals () 방법만 다시 썼을 뿐 hashCode () 방법을 다시 쓰지 않았다면, 두 대상이 같을 때 (equals () 방법이 되돌아오는
true
) 에도 이 두 대상은 같은 주소로 돌아갈 방법이 없다. 이럴 때 해시표를 사용하면 문제가 생길 수 있다.예를 들면 다음과 같습니다.
import java.util.HashSet;
/**
* @Author shenghai
* @Date 4/20 13:20
*/
public class test1 {
public static void main(String[] args) {
// Person ,
Person p1 = new Person("abc", 111);
Person p2 = new Person("abc", 111);
Person p3 = new Person("ccc", 200);
// HashSet
HashSet set = new HashSet<>();
set.add(p1);
set.add(p2);
set.add(p3);
// p1 p2, hashCode()
System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)
", p1.equals(p2), p1.hashCode(), p2.hashCode());
// set
System.out.printf("set:%s
", set);
}
private static class Person {
int age;
String name;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(this == obj) {
return true;
}
//
if(this.getClass() != obj.getClass()) {
return false;
}
Person person = (Person)obj;
return name.equals(person.name) && age==person.age;
}
}
}
/**
* :
* p1.equals(p2) : true; p1(460141958) p2(1163157884)
* set:[euqalsAndHashcode.test1$Person@74a14482, euqalsAndHashcode.test1$Person@4554617c,
* euqalsAndHashcode.test1$Person@1b6d3586]
*/
이럴 때, 비록 우리가 equals () 방법을 사용하면 되돌아갈 수 있지만
true
.그러나 분명히 p1과 p2를HashSet에 추가할 때HashSet은 이 두 대상이 같지 않다고 판정했다.왜 이런 상황이 생겼을까?이것은 p1과 p2의 내용은 같지만 그것들의hashCode()가 같지 않기 때문이다.그래서 HashSet은 p1과 p2를 추가할 때 서로 다르다고 생각한다.그러니 이제 해시코드 () 방법을 다시 써 봅시다.
import java.util.HashSet;
import java.util.Objects;
/**
* @Author shenghai
* @Date 4/20 13:20
*/
public class test2 {
public static void main(String[] args) {
// Person ,
Person p1 = new Person("abc", 111);
Person p2 = new Person("abc", 111);
Person p3 = new Person("ccc", 200);
// HashSet
HashSet set = new HashSet<>();
set.add(p1);
set.add(p2);
set.add(p3);
// p1 p2, hashCode()
System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)
", p1.equals(p2), p1.hashCode(), p2.hashCode());
// set
System.out.printf("set:%s
", set);
}
private static class Person {
int age;
String name;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(this == obj) {
return true;
}
//
if(this.getClass() != obj.getClass()) {
return false;
}
Person person = (Person)obj;
return name.equals(person.name) && age==person.age;
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
}
}
/**
* :
* p1.equals(p2) : true; p1(100756) p2(100756)
* set:[euqalsAndHashcode.test2$Person@18994, euqalsAndHashcode.test2$Person@19bfc]
*/
equals () 방법과 hashCode () 방법을 다시 쓰면 모든 것이 문제없습니다 ~
마지막으로 equals () 방법과 hashCode () 방법에 관한 규정을 요약해 보겠습니다.
true
되돌아온다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.