JAVA에서해시를 기반으로Key - Value 쌍데이터를 저장하는자료구조( ex.HashSet,HashMap)에서Key Type을 특정클래스로 지정 및Key 객체를 활용해Value를 찾을 경우
。단순하게인스턴스 멤버가 동일한Key 객체를 통해 검색 시Value를 return 받을 수 없다.import java.util.Map; import java.util.HashMap; class KeyClass { private final int id1 ; private final int id2 ; public KeyClass(int id1 , int id2) { this.id1 = id1; this.id2 = id2; } } public class testcase1 { public static void main(String[] args) { Map<KeyClass , String> map = new HashMap<KeyClass , String>(); map.put(new KeyClass(1,1), "lee"); System.out.println(map.get(new KeyClass(1,1))); // null 출력 } }。
map.get(객체)를 통해객체간 비교로 해당하는 데이터를 찾을 때 단순하게참조형 변수를 비교하여객체가 저장된Heap영역의주소의 비교를 수행
▶ 내부인스턴스변수등의 요소가 동일한객체로 검색을 수행해도객체참조주소가 다르므로 검색이 불가능.
。KeyClass내에equals(),hashCode()를 함께 추가로메소드 오버라이딩하여해시값을 사용하는자료구조내에서 논리적인동일객체여부를 판단
▶해시기반 자료구조가 아닌경우equals()만 구현import java.util.Map; import java.util.HashMap; import java.util.Objects; class KeyClass { private final int id1 ; // 불변변수 private final int id2 ; public KeyClass(int id1 , int id2) { this.id1 = id1; this.id2 = id2; } @Override public int hashCode() { // 객체 내 인스턴스변수값을 int의 해시값으로 만든 후 return // Hash 자료구조 에서 객체 비교 수행 시 해당 해시값으로 비교 return Objects.hash(id1, id2); } @Override public boolean equals(Object obj) { // 객체의 메모리주소값이 동일한 경우 true 반환 if ( this == obj ) return true; if ( obj instanceof KeyClass k ) // 객체 내부 인스턴스변수가 동일한 경우 true 반환 return this.id1 == k.id1 && this.id2 == k.id2; // 두 객체가 동일하지 않은 경우 false 반환 return false; } } public class testcase1 { public static void main(String[] args) { Map<KeyClass , String> map = new HashMap<KeyClass , String>(); map.put(new KeyClass(1,1), "lee"); System.out.println(map.get(new KeyClass(1,1))); // lee 출력 } }
해시기반자료구조에서객체를 비교하는 원리
。HashMap,HashSet의 경우자료구조객체.get(키객체)를 통해 전달된Key객체를 다음 2단계를 거쳐자료구조내객체의 비교를 수행 후 존재하면Value를 return한다.
▶ 다음 단계에서 일치하지 않는경우자료구조내 다음키객체와 비교 수행
1.Key 객체의hashCode()에서 return되는int의해시값을 통해 입력된키객체와 저장된키객체간해시값이 일치하는지 판단
2.해시값이 동일한 경우 두객체간equals()를 통해 비교 후 동일한 경우 해당하는Value반환
▶equals()로 동일한객체는hashCode()의해시값도 동일해야함.
hashCode():
。객체의해시값을 반환하는method
▶ 보통Objects.hash(인스턴스변수1,...)로해시값을 생성하여 return.
。java.lang.Object 클래스의Method로서메소드 오버라이딩을 통해 재정의하여해시값을 반환
。클래스가HashSet,HashMap의Generic에 정의된 경우 해당자료구조는해시값을 통해클래스 객체간 비교를 수행하므로 해당클래스에hashCode()를 구현해야한다.@Override public int hashCode() { // 객체 내 인스턴스변수값을 int의 해시값으로 만든 후 return // Hash 자료구조 에서 객체 비교 수행 시 해당 해시값으로 비교 return Objects.hash(id1, id2); }
Objects.hash(변수1, 변수2,...):java.util.Objects
。복수의변수를 기반으로해시코드를 생성
equals(객체)
。객체를 비교하는메소드
。java.lang.Object 클래스의Method로서메소드 오버라이딩을 통해 재정의하여 비교 결과를boolean으로 return
▶String의equals()도 동일하게메소드 오버라이딩으로 구현한메소드로서 두개문자열의 비교를 수행@Override public boolean equals(Object obj) { // 객체의 메모리주소값이 동일한 경우 true 반환 if ( this == obj ) return true; // obj가 KeyClass 객체인 경우 KeyClass로 캐스팅 후 변수 k로 할당 if ( obj instanceof KeyClass k ) // 객체 내부 인스턴스변수가 동일한 경우 true 반환 return this.id1 == k.id1 && this.id2 == k.id2; // 두 객체가 동일하지 않은 경우 false 반환 return false; }
객체 instanceof 클래스
。ObjectType으로 선언된객체가특정 클래스또는특정 인터페이스에 소속하는지객체 여부를 확인 후boolean을 return하는연산자
패턴매칭
。객체 instanceof 클래스를 사용 시 해당클래스에 해당하는 경우명시적 캐스팅없이객체를클래스로캐스팅하여 할당하도록 축약한 문법
▶Java 16에서 도입if (obj instanceof KeyClass) { KeyClass k = (KeyClass) obj; // 명시적 캐스팅 return this.id1 == k.id1 && this.id2 == k.id2; }if (obj instanceof KeyClass k) return this.id1 == k.id1 && this.id2 == k.id2;