일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- c언어
- redis
- C
- spring webflux
- 파이썬
- JPA
- Heap
- Data Structure
- 알고리즘
- JavaScript
- Kafka
- IT
- mongoDB
- 자바
- design pattern
- 디자인 패턴
- MySQL
- MSA
- Algorithm
- Spring
- 컴퓨터구조
- OS
- Galera Cluster
- 자료구조
- react
- 네트워크
- Proxy
- 백준
- 운영체제
- Java
Archives
- Today
- Total
시냅스
Java Equals와 HashCode, == 와 차이 본문
Equals 와 == 의 차이
Primitive type (원시타입)
- Call by value
- 주소로 변수 값을 바로 확인하여 계산하기 때문에 == 비교가 가능
Reference type (원시타입 이외 모두)
- Call by reference
- 주소값을 참조(포인터) 하여 사용하기 때문에 == 비교를 하게 될 경우 주소값을 비교하게 된다.
- String을 new (builder, buffer 포함)를 사용하지 않고 리터럴로 생성한 경우
- String은 string constant pool 이라는 영역에 속한다. (intern)
- 같은 값에 한해서는 같은 주소값을 같게 된다.
- 따라서 == 비교가 가능하다.
- 이때 객체 내부에 Equals()를 override 하여 객체간 값에 대한 비교를 할 수 있다.
Equals 와 HashCode
- Eqauls와 HashCode는 한 셋트다
- Hash 값을 사용하는 Collection(HashSet, HashMap, HashTable)을 제외하면 사실 Equals만 사용해도 구현은 무관하다
- 다만, 요구사항이 변한다거나, 협업 환경에서의 통일, 성능 등을 고려하면 같이 구현하는 것이 바람직하다.
- Equals 는 재정의하여 주소값을 가지는 모든 객체의 값에 관한 비교를 수행할 수 있도록 한다.
- HashCode 는 Hash 알고리즘에 의해 객체의 주소값을 토대로 일정한 리턴값을 보내주게 된다.
- 자바 API에서는 다음과 같이 말한다.
- 어떤 두개 객체에 대하여 equals() 메소드를 사용하여 비교한 결과가 true인 경우, 두 객체의 hashcode() 메소드를 호출하면 동일한 int 값을 리턴해야 한다.
- 두 객체를 equals() 메소드를 사용하여 비교한 결과 false를 리턴했다고 해서 hashcode() 메소드를 호출한 int 값이 무조건 달라야 할 필요는 없다. 하지만, 이 경우 서로 다른 int 값을 제공하면 hashtable의 성능을 향상시키는 데 도움이 된다.
- 종합하면, HashCode로 객체에 관한 판별을 하고, Equals로 객체에 관한 값을 비교할 수 있게 한다.
예시코드
class AClass {
int a;
int b;
Cclass c;
public AClass(int a, int b) {
this.a = a;
this.b = b;
}
public AClass(int a, int b, Cclass c) {
this.a = a;
this.b = b;
this.c = c;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AClass)) return false;
AClass aClass = (AClass) o;
if (a != aClass.a) return false;
if (b != aClass.b) return false;
return c != null ? c.equals(aClass.c) : aClass.c == null;
}
@Override
public int hashCode() {
int result = a;
result = 31 * result + b;
result = 31 * result + (c != null ? c.hashCode() : 0);
return result;
}
}
- A클래스는 내부에 값과 객체 C를 가진다.
class Cclass {
private int a;
public Cclass(int a) {
this.a = a;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Cclass)) return false;
Cclass cclass = (Cclass) o;
return a == cclass.a;
}
@Override
public int hashCode() {
return a;
}
}
- C클래스는 값 하나를 가진다.
public class Eqauls {
public static void main(String[] args) {
AClass aa = new AClass(1, 2, new Cclass(1));
AClass bb = new AClass(1, 2, new Cclass(1));
System.out.println(aa.equals(bb)); // true
System.out.println(aa == bb); // false
AClass aa1 = new AClass(1, 2);
AClass bb1 = new AClass(1, 2);
System.out.println(aa1.equals(bb1)); // true
System.out.println(aa == bb); // false
Set<AClass> a1 = new HashSet<>();
a1.add(aa1);
a1.add(bb1);
System.out.println(a1.size()); // 1
}
}
- HashSet인 a1은 AClass에서 재정의한 Equals 나 HashCode를 삭제한다면 객체가 같지 않다고 판별한 이유로 사이즈는 2가 나올 것이다.
'Java, Spring' 카테고리의 다른 글
Java 코드로 보는 Lock Striping 과 ConcurrentHashMap, CAS (Compare-And-Swap) (2) | 2023.02.17 |
---|---|
Java 프로세스 동기화 process synchronization 정리 (0) | 2023.02.11 |
Java Annotation Processor 정리 (0) | 2023.02.11 |
Java 가비지 컬렉션 Garbate Collection 정리 (0) | 2023.02.08 |
Java 함수형 프로그래밍 (0) | 2023.02.06 |
Comments