자바 에 서 는 두 대상 이 같은 지 아 닌 지 를 어떻게 판단 합 니까?
1.equals 의 역할 및=의 차이.
equals 는 두 대상 이 같은 지 아 닌 지 를 판단 하 는 데 사용 된다.equals 는 보통 두 대상 의 내용 이 같 는 지 비교 하 는 데 사용 되 며,==두 대상 의 주소 가 같 는 지 비교 하 는 데 사용 된다.equals 방법 은 기본적으로'=='Object 클래스 의 equals 방법 과 같 으 며,주소 가 같 으 면 대상 이 같다 고 판단 합 니 다.이것 은 우리 가 새로 만 든 모든 클래스 가 이퀄 스 를 복사 하 는 방법 이 없다 면 두 대상 이 같은 지 여 부 를 판단 할 때'==',즉 두 대상 의 주소 가 같은 지 여 부 를 판단 하 는 것 을 의미한다.Object 클래스 의 equals 방법 은 다음 과 같 습 니 다.
public boolean equals(Object obj) {
return (this == obj);
}
그러나 우리 의 실제 개발 에 서 는 두 대상 의 내용 이 같다 고 생각 할 때 두 대상 이 같 고 equals 는 true 로 돌아간다.대상 내용 이 다 르 면 false 로 돌아 갑 니 다.
public class EqualTest {
public static void main(String[] args) {
Person p1 = new Person(10," ");
Person p2 = new Person(10," ");
System.out.println(p1.equals(p2));
}
}
class Person{
int age;
String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person 이 equals 방법 을 복사 하지 않 으 면 기본적으로 Object 의 equals 를 사용 합 니 다.즉,두 대상(p1 과 p2)의 메모리 주 소 를 판단 합 니 다.p1 과 p2 는 메모리 주소 가 다 르 기 때문에 출력 결 과 는 false 입 니 다.우리 가 equals 방법 을 복사 하면?우 리 는 이름과 나이 가 같은 사람 이 같은 사람 이 라 고 생각한다.그러면 p1 과 p2 는 모두 10 세의 장 삼 을 나타 내 는데 이 두 대상 은 같 아야 한다.복사 한 equals 방법 은 다음 과 같 습 니 다.
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
마찬가지 로 상술 한 용례 를 집행 하여 얻 은 결 과 는 true 이다.BTW:equals 방법 이 true 로 돌아간다 면==역시 true 입 니까?꼭 트 루 는 아니 야.equals 가 true 로 돌아 갈 수 있 는 두 가지 가능성 이 있 습 니 다.하 나 는 두 대상 의 주소 가 같 고 하 나 는 두 대상 의 내용 이 같 습 니 다.내용 이 같 으 면 주소 가 다 를 수 있 기 때문에==비교 결 과 는 false 일 수 있 습 니 다.우 리 는 main 방법 에=에 대한 판단 을 더 하면 다음 과 같다.
public static void main(String[] args) {
Person p1 = new Person(10," ");
Person p2 = new Person(10," ");
System.out.println(p1.equals(p2));
System.out.println(p1 == p2);
}
출력 결과 가 뚜렷 합 니 다.p1==p2 의 결 과 는 false 입 니 다.
자바 에서 equals 에 대한 요 구 를 추가 합 니 다:
1. : x.equals(y) "true", y.equals(x) "true"。
2. :x.equals(x) "true"。
3. : x.equals(y) "true", y.equals(z) "true", z.equals(x) "true"。
4. : x.equals(y) "true", x y , x.equals(y) , "true"。
5. ,x.equals(null), "false";x.equals( x ) "false"。
2.hashCode 의 역할 및 equals 와 의 관계.
hashCode 의 역할 은 해시 코드 를 얻 는 것 이 고 해시 코드 라 고도 할 수 있 습 니 다.실제 반환 값 은 int 형 데이터 입 니 다.대상 이 해시 표 에 있 는 위 치 를 확인 하 는 데 사용 합 니 다.Object 에 hashcode 방법 이 있다 는 것 은 모든 종류 에 hashCode 방법 이 있다 는 것 을 의미한다.그러나 hashcode 는 특정한 종류의 산 목록 을 만 들 때 만 유용 합 니 다.hashcode 값 에 따라 대상 이 산 목록 에 있 는 위 치 를 확인 해 야 하지만 다른 경우 에는 소 용이 없습니다.자바 에 서 는 본질 적 으로 산 목록 류 에서 흔히 볼 수 있 는 HashMap,HashSet,HashTable 이 있 기 때문에 대상 이 산 목록 에서 사용 하지 않 는 다 면 hashCode 방법 을 복사 할 필요 가 없습니다.그러나 일반적인 상황 에서 우 리 는 hashCode 방법 을 복사 합 니 다.왜냐하면 누가 이 대상 이 더 이상 hashMap 등 이 나타 나 지 않 을 것 이 라 고 보장 할 수 있 습 니까?예 를 들 어 두 대상 이 equals 가 같 을 때 hashcode 는 반드시 같 지 않다.
public class EqualTest {
public static void main(String[] args) {
Person p1 = new Person(10, " ");
Person p2 = new Person(10, " ");
System.out.println(
"p1.equals(p2)=" + p1.equals(p2) + ", p1.hashcode=" + p1.hashCode() + ", p2.hashcode=" + p2.hashCode());
}
}
class Person {
int age;
String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
Person 은 hashCode 를 복사 하 는 방법 이 없습니다.Object 의 기본 hashCode 를 사용 하여 이 루어 집 니 다.출력 결 과 는 다음 과 같 습 니 다.
p1.equals(p2)=true, p1.hashcode=246688959, p2.hashcode=1457895203
결 과 를 보면 equals 는 같 지만 p1 과 p2 의 hashcode 는 다르다.
Person 이 산 목록 의 클래스 에 사용 된다 면,여 기 는 HashSet 로 테스트 합 니 다.
public class EqualTest {
public static void main(String[] args) {
Person p1 = new Person(10, " ");
Person p2 = new Person(10, " ");
System.out.println(
"p1.equals(p2)=" + p1.equals(p2) + ", p1.hashcode=" + p1.hashCode() + ", p2.hashcode=" + p2.hashCode());
HashSet<Person> set = new HashSet<Person>();
set.add(p1);
set.add(p2);
System.out.println(set);
}
}
class Person {
int age;
String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}
}
출력 결과
p1.equals(p2)=true, p1.hashcode=246688959, p2.hashcode=1457895203
[Person [age=10, name= ], Person [age=10, name= ]]
p1 은 p2 의 equals 와 같 습 니 다.우 리 는 두 대상 이 같다 고 생각 합 니 다.그러나 이 두 대상 이 동시에 나타 나 면 hashSet 에 두 개의 똑 같은 요소 가 나타 나 지 않 습 니 다.그 문 제 는 어디 에 있 습 니까?
과정:대상 을 HashSet 에 추가 할 때 HashSet 은 대상 의 hashcode 값 을 먼저 계산 하여 대상 이 가입 한 위 치 를 판단 하 는 동시에 가입 한 대상 의 hashcode 값 과 비교 합 니 다.일치 하 는 hashcode 가 없 으 면 Hashset 은 대상 이 중복 되 지 않 았 다 고 가정 합 니 다.그러나 같은 hashcode 값 의 대상 이 발견 되면 equals()방법 으로 hashcode 와 같은 대상 이 정말 같 는 지 확인 합 니 다.둘 이 같 으 면 Hashset 은 가입 에 성공 하지 못 합 니 다.
우 리 는 개선 해서 hashcode 방법 을 복사 합 니 다.다음 과 같 습 니 다.
class Person {
int age;
String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}
}
결과 다시 실행:
p1.equals(p2)=true, p1.hashcode=776160, p2.hashcode=776160
[Person [age=10, name= ]]
그래서 set 에 Person 값 이 하나 밖 에 없 는 것 을 보 았 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.