본문 바로가기
Java, JSP

[Java/자바] 객체 비교, equals()와 hashCode()

by LasBe 2022. 1. 10.
반응형

⚡️ equals()와 hashCode()


equals와 hashCode 메소드는 기본적으로 최상위 클래스인 Object의 메소드입니다.

 

즉 생성되는 모든 클래스는 Object에게 상속받고 있기 때문에 equals와 hashCode 메소드를 사용 가능합니다.

 

아래와 같이 둘은 맥락은 비슷하지만 디테일에서 차이가 있습니다.

 

equals()

  • 두 객체의 내용이 동일한지 확인하는 메소드
  • 동일한 메모리 주소를 가르키면 true리턴

 

hashCode()

  • 비교 시 두 객체가 같은 객체인지 확인할 수 있는 메소드
  • 객체의 유일한 정수값을 반환하는 메소드

그럼 아래에서 더 자세한 사용법을 알아보겠습니다.

 

 

 

⚡️ Equals()


멤버로 이름을 가지고 있는 클래스를 하나 생성해줍니다.

class Student{
	String name;
	Student(String name){
		this.name=name;
	}
}

 

메인문에서는 클래스가 같은 s1, s2 객체를 만들어줍니다.

Student s1 = new Student("A");
Student s2 = new Student("A");

 

그리고 동등 비교 연산자인 (==)과 euqals() 메소드를 함께 확인해봅시다.

System.out.println("s1 == s2 : "+ (s1==s2));
System.out.println("s1.equals(s2) : "+ s1.equals(s2));
System.out.println("s1.name == s2.name : "+ (s1.name==s2.name));
System.out.println("s1.name.equals(s2.name) : "+ s1.name.equals(s2.name));

놀랍게도 같은 결과가 나왔습니다.

 

그 이유는 아래의 Object 클래스의 equals() 메소드를 직접 확인해보면 알 수 있습니다.

// Object의 기본 equals 메서드
public boolean equals(Object obj) {
    return (this == obj);
}

코드를 보면 기본적으로 동등 비교 연산자를 사용해 객체를 비교하기 때문에 동일한 클래스의 객체에 동일한 값을 가지고 있어도

주소 값이 다르기때문에 동일하지 않다는 결과가 나오게 됩니다.

 

그렇다면 참조값에 관계없이 객체 내부의 값이 같으면 중복되는 것으로 판단하는 논리적 동등을 어떻게 구현하는지 알아보겠습니다.

 

 

⚡️ 논리적 동등


두 객체가 논리적 동등을 이루기 위해서는 두 가지 조건이 필요합니다.

  1. 객체1.hashCode() == 객체2.hashCode() -> true
  2. 객체1.equals(객체2) -> true

우선 객체 둘의 해시코드 값이 같아야하고 그 다음 equals() 리턴 값으로 ture를 받으면 논리적으로 동등한 객체라고 인정됩니다.

 

그러기 위해서는 클래스 내부에서 equals()와 hashCode()를 오버라이딩 해주는 작업이 필요합니다.

 

class Student{
	String name; int age;
	Student(String name, int age){
		this.name=name; this.age=age;
	}
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Student) {
			Student st = (Student)obj; // 슈퍼클래스를 다운캐스팅
			return name == st.name && age==st.age;
		} 
        	else return false;
	}
	@Override
	public int hashCode() {
		return name.hashCode()+age;
	}
}

 

equals() 메소드는 동일한 클래스에 멤버변수의 값이 동일하다면 true로 반환하도록,

hashCode() 메소드는 해쉬 알고리즘을 통해 같은 값이면 동일한 해쉬 코드가 반환되도록 오버라이딩 합니다.

 

그럼 잘 작동하는지 확인해보겠습니다.

 

s1과 s2는 같은 값, s3는 다른 값으로 객체를 생성해줍니다.

Student s1 = new Student("A", 10);
Student s2 = new Student("A", 10);
Student s3 = new Student("B", 10);

 

위에서 설명한 것과 같이 equals와 hashCode 메소드에서 모두 true를 리턴받으면 논리적으로 동등한 객체로 인정합니다.

if(s1.equals(s2) && s1.hashCode()==s2.hashCode()) {
	System.out.println("s1과 s2는 논리적으로 동등합니다.");
	System.out.println("s1.hashCode() : "+s1.hashCode()+" / s2.hashCode : "+s2.hashCode());
}
else {
	System.out.println("s1과 s2는 논리적으로 동등하지 않습니다.");
	System.out.println("s1.hashCode() : "+s1.hashCode()+" / s2.hashCode : "+s2.hashCode());
}

System.out.println("==========================");

if(s1.equals(s3) && s1.hashCode()==s3.hashCode()){
	System.out.println("s1과 s3는 논리적으로 동등합니다.");
	System.out.println("s1.hashCode() : "+s1.hashCode()+" / s3.hashCode : "+s3.hashCode());
}
else {
	System.out.println("s1과 s3는 논리적으로 동등하지 않습니다.");
	System.out.println("s1.hashCode() : "+s1.hashCode()+" / s3.hashCode : "+s3.hashCode());
}

결과는 위와 같이 잘 나오는 것을 볼 수 있습니다.

 

 

더보기

자바 equals(), hashCode(), 객체비교, 논리적 동등, 동등성, 물리적 동등

반응형

댓글


오픈 채팅