import java.io.*;
import java.util.*;
public class Template {
static class Point{
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj){
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Point point = (Point)obj;
return x == point.x && y == point.y;
}
@Override
public int hashCode(){
return Objects.hash(x,y);
}
}
public static void main(String[] args){
Map<Point, Integer> pointMap = new HashMap<>();
Point point1 = new Point (3,4);
Point point2 = new Point (3,4);
Point point3 = null;
Point point4 = null;
pointMap.put(point1, pointMap.getOrDefault(point1, 0) + 1);
pointMap.put(point2, pointMap.getOrDefault(point2, 0) + 1);
pointMap.put(point3, pointMap.getOrDefault(point3, 0) + 1);
pointMap.put(point4, pointMap.getOrDefault(point3, 0) + 1);
// equals, hash 오버라이드 하지않을경우
// 예상 출력 : 1 1 1 1
// 실제 : 1 1 2 2
// 같은 좌표만 묶지 못함.
System.out.println(pointMap.get(point1));
System.out.println(pointMap.get(point2));
System.out.println(pointMap.get(point3));
System.out.println(pointMap.get(point4));
// equals, hash 오버라이드 했을경우
// 예상 출력 : 2 2 2 2
// 실제 출력 : 2 2 2 2
}
}
위에서는 Map<Point, Integer>으로 객체의 카운팅을 하는 맵이다.
요구사항은 같은 좌표를 동등시하여 카운트를 올리는 방식이다.
해시맵에서는 그대로 사용하면 위의 (3,4) 좌표는 서로 다르게 계산된다.
좀더 구체적으로 해시맵의 put방식을 살펴보면,
hashmap은 키의 동등성을 비교할때 hashcode를 먼저 사용하고, equals를 통해 추가적으로 확인한다.
즉, equals를 오버라이딩하지않으면 객체 메모리 주소 기반으로 hashcode를 반환하고, equals는 주소값을 동등비교밖에 하지않는다.
상위 메소드를 타고 올라가면
주소 동등비교 밖에 없다.
값을 비교하려면 따로 커스텀해서 지정해줘야한다.
따라서 원하는 연산인 두 좌표가 같음에도 불구하고 같은 좌표로 카운트되지않는다.
문제로 돌아가서 커스텀하고 싶은것은 hashcode 함수도 포함이다.
@Override
public int hashCode(){
return Objects.hash(x,y);
}
@Override
public boolean equals(Object obj){
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Point point = (Point)obj;
return x == point.x && y == point.y;
}
일단 기본적으로 주소값이 같을때 -> true
객체가 null이거나 클래스 타입이 다를때 -> false
obj타입이 point인데, 각 변수가 같을때 -> true
출처