
equals를 사용한 테스트 코드를 작성하고, 실제 기능을 구현한 뒤 테스트 해보았지만, 실패했다.
분명 내 코드에는 문제가 없다고 생각했고, 열심히 디버깅을 해 본 결과 equals 메소드에서 서로 다른 메모리 주소를 갖기 때문에 false를 반환했던 것이다.
이러한 문제는 equals, hashcode 재정의를 통해 해결할 수 있지만, 좀 더 근본적인 이유를 간단히 정리해보고자 한다.
자바의 동일성 (identify), 동등성 (equality)
먼저 자바의 동일성과 동등성에 대해 알아보자.
동일성 (identify) 이란 무엇일까?
나는 동일성 (identify) 이란 태생부터 존재하는 유일한 것이라고 생각했다. 나 홍길동은 태어나서 존재하는 단 한 명의 인간이다.
나와 같은 이름을 가진 다른 홍길동이 존재한다 하더라도 같은 홍길동이라고 볼 수 없다.
public class Main {
public static void main(String[] args) {
List<People> studyGroup = new ArrayList<>();
People gildong1 = new People("gildong", 20);
People gildong2 = new People("gildong", 20);
studyGroup.add(gildong1);
studyGroup.add(gildong2);
// 스터디 그룹의 첫번째 멤버와 비교
System.out.println(gildong1.equals(studyGroup.get(0))); // true
// 스터디 그룹의 두번째 맴버와 비교
System.out.println(gildong2.equals(studyGroup.get(0))); // false
}
}
첫번째로 스터디에 들어간 홍길동과 두 번째로 스터디로 들어간 홍길동은 다른 사람이다.
따라서 스터디 그룹의 첫번째 멤버와 비교했을 때는 true를 반환하지만,
스터디 그룹의 두번째 멤버와 비교했을 때는 false를 반환한다.
즉 동일성은 태생부터 같은 존재라고 이해할 수 있다.
그렇다면 동등성 (equality) 은 무엇일까?
동등성 (equality) 은 같은 속성을 갖는지를 의미한다.
여러 가지 과일들이 존재한다. 초록색 사과가 있고, 빨간색 사과, 포도가 있다. 모두 과일이란 클래스를 통해 관리된다.
나는 과일의 종류에 따라 구분하고 싶어 다음과 같이 코드를 작성했다.
public class Main {
public static void main(String[] args) {
List<Fruit> fruits = new ArrayList<>();
Fruit greenApple = new Fruit("apple");
Fruit redApple = new Fruit("apple");
Fruit grape = new Fruit("grape");
fruits.add(greenApple);
fruits.add(redApple);
fruits.add(grape);
// 사과인지 확인하기
System.out.println(new Fruit("apple").equals(fruits.get(0))); // false
System.out.println(new Fruit("apple").equals(fruits.get(1))); // false
System.out.println(new Fruit("apple").equals(fruits.get(2))); // false
}
}
하지만 과일들은 모두 사과가 아니라고 나와 모두 폐기 처분되었다.
의도는 사과의 속성을 갖는 과일들은 true가 나와야 한다.
즉 동일성은 같은 속성을 갖는 존재라고 이해할 수 있다.
최대한 풀어 정리하려 했지만 한글로 정리하기엔 모호함이 많기에 영어의 의미로 본다면 더욱 와닿을 것 같다.
세상에 존재하는 단 하나를 비교하는 동일함 identify, 같은 속성인지 비교하는 동등성 equality
equals, hashcode 재정의
public class Fruit {
private String type;
public Fruit(String type) {
this.type = type;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Fruit fruit = (Fruit) o;
return Objects.equals(type, fruit.type);
}
@Override
public int hashCode() {
return Objects.hash(type);
}
}
다음과 같이 인텔리제이 단축키 cmd + n을 통해 빠르게 재정의할 수 있다.
equals로 같은 속성(필드값)을 가질 때 같은 객체로 판단하도록 equals를 재정의한다는 것은 이해가 되었다.
하지만 hashcode는 뭐길래 재정의 하는 것일까?
사실 실질적인 동작 순서는 hashcode 값을 비교한 뒤 equals 메서드가 수행되어 속성값을 비교한다.
즉, 속성값들이 같은 객체들은 같은 hashcode를 가져야 한다.
따라서 특별한 상황이 아니라면 equals와 hashcode는 함께 재정의해 사용하도록 하자.
'Study > Java' 카테고리의 다른 글
[Java] 불변 객체 (Immutable Object) 란? (0) | 2023.07.23 |
---|---|
[Java] 자바의 스레드와 동작 과정 (0) | 2023.07.15 |
[JUnit] 다양한 Assertions 사용하기 (1) | 2023.07.11 |
[Java] 코딩테스트에 자주 쓰는 문법 정리 (0) | 2022.09.29 |
[Java / IntelliJ] 인텔리제이 입출력 txt로 받기 (0) | 2022.09.29 |

equals를 사용한 테스트 코드를 작성하고, 실제 기능을 구현한 뒤 테스트 해보았지만, 실패했다.
분명 내 코드에는 문제가 없다고 생각했고, 열심히 디버깅을 해 본 결과 equals 메소드에서 서로 다른 메모리 주소를 갖기 때문에 false를 반환했던 것이다.
이러한 문제는 equals, hashcode 재정의를 통해 해결할 수 있지만, 좀 더 근본적인 이유를 간단히 정리해보고자 한다.
자바의 동일성 (identify), 동등성 (equality)
먼저 자바의 동일성과 동등성에 대해 알아보자.
동일성 (identify) 이란 무엇일까?
나는 동일성 (identify) 이란 태생부터 존재하는 유일한 것이라고 생각했다. 나 홍길동은 태어나서 존재하는 단 한 명의 인간이다.
나와 같은 이름을 가진 다른 홍길동이 존재한다 하더라도 같은 홍길동이라고 볼 수 없다.
public class Main {
public static void main(String[] args) {
List<People> studyGroup = new ArrayList<>();
People gildong1 = new People("gildong", 20);
People gildong2 = new People("gildong", 20);
studyGroup.add(gildong1);
studyGroup.add(gildong2);
// 스터디 그룹의 첫번째 멤버와 비교
System.out.println(gildong1.equals(studyGroup.get(0))); // true
// 스터디 그룹의 두번째 맴버와 비교
System.out.println(gildong2.equals(studyGroup.get(0))); // false
}
}
첫번째로 스터디에 들어간 홍길동과 두 번째로 스터디로 들어간 홍길동은 다른 사람이다.
따라서 스터디 그룹의 첫번째 멤버와 비교했을 때는 true를 반환하지만,
스터디 그룹의 두번째 멤버와 비교했을 때는 false를 반환한다.
즉 동일성은 태생부터 같은 존재라고 이해할 수 있다.
그렇다면 동등성 (equality) 은 무엇일까?
동등성 (equality) 은 같은 속성을 갖는지를 의미한다.
여러 가지 과일들이 존재한다. 초록색 사과가 있고, 빨간색 사과, 포도가 있다. 모두 과일이란 클래스를 통해 관리된다.
나는 과일의 종류에 따라 구분하고 싶어 다음과 같이 코드를 작성했다.
public class Main {
public static void main(String[] args) {
List<Fruit> fruits = new ArrayList<>();
Fruit greenApple = new Fruit("apple");
Fruit redApple = new Fruit("apple");
Fruit grape = new Fruit("grape");
fruits.add(greenApple);
fruits.add(redApple);
fruits.add(grape);
// 사과인지 확인하기
System.out.println(new Fruit("apple").equals(fruits.get(0))); // false
System.out.println(new Fruit("apple").equals(fruits.get(1))); // false
System.out.println(new Fruit("apple").equals(fruits.get(2))); // false
}
}
하지만 과일들은 모두 사과가 아니라고 나와 모두 폐기 처분되었다.
의도는 사과의 속성을 갖는 과일들은 true가 나와야 한다.
즉 동일성은 같은 속성을 갖는 존재라고 이해할 수 있다.
최대한 풀어 정리하려 했지만 한글로 정리하기엔 모호함이 많기에 영어의 의미로 본다면 더욱 와닿을 것 같다.
세상에 존재하는 단 하나를 비교하는 동일함 identify, 같은 속성인지 비교하는 동등성 equality
equals, hashcode 재정의
public class Fruit {
private String type;
public Fruit(String type) {
this.type = type;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Fruit fruit = (Fruit) o;
return Objects.equals(type, fruit.type);
}
@Override
public int hashCode() {
return Objects.hash(type);
}
}
다음과 같이 인텔리제이 단축키 cmd + n을 통해 빠르게 재정의할 수 있다.
equals로 같은 속성(필드값)을 가질 때 같은 객체로 판단하도록 equals를 재정의한다는 것은 이해가 되었다.
하지만 hashcode는 뭐길래 재정의 하는 것일까?
사실 실질적인 동작 순서는 hashcode 값을 비교한 뒤 equals 메서드가 수행되어 속성값을 비교한다.
즉, 속성값들이 같은 객체들은 같은 hashcode를 가져야 한다.
따라서 특별한 상황이 아니라면 equals와 hashcode는 함께 재정의해 사용하도록 하자.
'Study > Java' 카테고리의 다른 글
[Java] 불변 객체 (Immutable Object) 란? (0) | 2023.07.23 |
---|---|
[Java] 자바의 스레드와 동작 과정 (0) | 2023.07.15 |
[JUnit] 다양한 Assertions 사용하기 (1) | 2023.07.11 |
[Java] 코딩테스트에 자주 쓰는 문법 정리 (0) | 2022.09.29 |
[Java / IntelliJ] 인텔리제이 입출력 txt로 받기 (0) | 2022.09.29 |