객체의 해시코드를 반환하는 메소드로 Object 클래스의 hashCode 메소드는 객체의 주소를 int로 변환해서 반환한다.
public class Object {
public native int hashCode(); //native로 OS의 메소드를 사용하므로 내용이 없다.(JNL)
}
hash 값을 사용하는 Collection(HashSet, HashMap, HashTable)을 사용할 때, equals() 결과가 true인 두 객체의 hashCode() 또한 같게 하기 위해 equals()를 오버라이딩하면 hahsCode() 또한 오버라이딩 해야 한다.
public class Car {
private final String name;
public Car(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return Objects.equals(name, car.name);
}
}
public static void main(String[] args){
Car car1 = new Car("foo");
Car car2 = new Car("foo");
System.out.println(car1.equals(car2)); // true 출력
}
List에 Car객체를 넣어주면 결과는 2가 될 것이다.
public static void main(String[] args) {
List<Car> cars = new ArrayList<>();
cars.add(new Car("foo"));
cars.add(new Car("foo"));
System.out.println(cars.size()); //2 출력
}
이번에는 Collections에 중복되지 않는 Car객체만 넣으라는 요구사항이 있어 Set을 사용한다 가정해본다.
public static void main(String[] args) {
Set<Car> cars = new HashSet<>();
cars.add(new Car("foo"));
cars.add(new Car("foo"));
System.out.println(cars.size()); //2 출력
}
이때 객체의 이름이 같아서 논리적으로는 같은 객체라 판단이 가능하지만, 출력 결과는 2가 나온다.
이는 hash값을 사용하는 Collections가 다음과 같은 과정을 거치기 때문이다.
앞의 코드는 hashCode가 재정의 되어있지 않아 Object 클래스의 hashCode 메소드가 사용되어 서로 다른 객체라 판단했기 때문에 2가 출력된다.
public class Car {
private final String name;
public Car(String name) {
this.name = name;
}
// intellij Generate 기능 사용
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return Objects.equals(name, car.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
따라서 다음과 같이 코드를 작성하여야 원하는 결과를 출력할 수 있다.