==와 equals()

호떡·2022년 7월 27일
0

==는 주소값이 같은지 아닌지 비교하는 것(참조타입의 경우)이고, equals() 메소드도 내부적으로 주소값을 비교하지만 String 클래스에서는 equals()를 재정의하여 내용을 비교하게 된다.


아래의 Person 클래스를 기준으로 설명하겠다.


public class Person {
	String name;
	int age;
    
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
    
    @Override
	public int hashCode() {
		return Objects.hashCode(name);
	}
	
	@Override
	public boolean equals(Object obj) {
		return name.equals(((Person)obj).name) && age == ((Person)obj).age;
	}
    
    @Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
} //end class

==연산자

기초 자료형에 대해서는 값을 비교해주고, 참조 자료형에 대해서는 주소값을 비교한다.

		//기초 자료형
		System.out.println(1==1);		//true
		//참조 자료형
		Person p1 = new Person("김싸피", 20);
		Person p2 = new Person("김싸피", 21);
		Person p3 = new Person("김싸피", 20);
        
    	System.out.println(p1 == p3);		//false

new 연산자는 힙 영역에 새로운 객체를 만들 때 사용하는 연산자로 이름 자체가 객체 생성 연산자이다. 즉 heap 영역에 객체를 새로 찍어내고 있다. 따라서 p1과 p3는 서로 다른 객체의 주소값을 각각 가지고 있다.



equals() 메소드

equals()는 최상위 클래스인 Object에 포함되어 있기 때문에 모든 하위 클래스에서 재정의 해서 사용 가능하다. 이같은 원리는 toString()에서도 살펴본 바 있다.

		public boolean equals(Object obj) {
        	return (this == obj);
    	}

Object 클래스의 equals()의 본 내용을 살펴보면 위와 같이 정의되어 있다. equals( )도 내부적으로는 ==연산자를 사용해 주소를 비교하는 것과 다름이 없다. 이는 곧 equals( )는 원래 주소값을 비교하는 메소드란 것이다.
하지만 우리가 String에서 사용하던 equals( )는 주소를 비교하는 것이 아닌 내용을 비교하는 것이었다. 이는 String 클래스에서 처음부터 equals( )가 문자열을 비교하게 재정의되어 만들어져있기 때문에 문자열 비교가 가능했던 것이다.
따라서 String이 아닌 다른 객체의 값(내용)을 비교하기 위해선 우리가 따로 equals( ) 메서드를 재정의하여 사용해야 한다.

    	Person p1 = new Person("김싸피", 20);
		Person p2 = new Person("김싸피", 21);
		Person p3 = new Person("김싸피", 20);
        
    	System.out.println(p1.equals(p2));		//false
		System.out.println(p1.equals(p3));		//true

💡참고 블로그( 링크텍스트 )



HashSet에서의 '같다'

HashSet은 객체들을 순서 없이 저장하고 동일한 객체는 중복 저장하지 않는다.
순서1. HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode( ) 메소드를 호출해서 해시코드를 얻어낸다. 그리고 이미 저장되어 있는 객체들의 해시코드와 비교한다. 만약 동일한 해시코드가 있다면
순서2. 다시 equals( ) 메소드로 두 객체를 비교해서 true가 나오면 동일한 객체로 판단하고 중복 저장을 하지 않는다.

		Set<Person> pset = new HashSet<>();

		Person p1 = new Person("김싸피", 20);
		Person p2 = new Person("김싸피", 21);
		Person p3 = new Person("김싸피", 20);

		pset.add(p1);
		pset.add(p2);
		pset.add(p3);
		System.out.println(pset);
		System.out.println(pset.size());

HashSet의 기준에 따른다면 어떤 객체들이 중복된다고(같다고) 판단했을까? 어떤 객체들이 저장되었을까? 결과는 다음과 같다.

HashSet은 p1과 p3를 같다고 판단하여 (사실은 Person 클래스에서 hashCode( ), equals( )에서 우리만의 기준으로 재정의하였기 때문에) 중복 저장하지 않고 한 개만 저장하였다.

== 연산자와 재정의된 equals( ) 메소드, 거기에 HashSet의 중복 판단 기준을 혼동하지 말자. 이 세 가지 개념은 서로 연동되는 것이 아니며 각자의 원리에 따라 같고 다름을 판단하고, 같고 다름에 따라 자료구조에 저장하고 말고가 결정될 뿐이다.

0개의 댓글