Java Set 자료구조에서 중복 객체 구분 방식

Jang990·2023년 2월 1일
0
post-custom-banner

22년 8월 22일 작성글

사용자 정의 객체

아래 코드는 내가 정의한 Member.class이다.

@Data
public class Member {
	private String name;
	private String address;
	private int grade;
	
	public Member(String name, String address, int grade) {
	   this.name = name;
	   this.address = address;
	   this.grade = grade;
	}
	
	@Override
	public String toString() {
	   return "이름: " + this.name + "\t학년:" + grade + "\t주소:" + address;
	}
}

Set에서는 객체의 중복을 확인하기 위해서 hashCode() 메서드를 호출하여 hashCode가 같은지 확인하고, 같다면 equals() 메서드를 호출하여 값을 비교한다.
그렇기때문에 Set 형식에서 다음 m1, m2 객체를 구분하기 위해서는 equals()hashCode() 메서드를 재정의 해야 한다.

Member m1 = new Member("Jang", "인천", 1);
Member m2 = new Member("Jang", "인천", 1);

다음과 같이 메서드를 재정의 해주면 된다. equals()hashCode() 메서드를 재정의에 관한 자세한 내용은 이펙티브 자바 Item 10, Item 11을 확인하자.

@Data
public class Member {
	...

	@Override
	public int hashCode() {   
	   return Objects.hash(this.name,
	         this.grade,
	         this.address);
	}
	
    @Override
	public boolean equals(Object obj) {
	   if(!(obj instanceof Member)) return false;
	   
	   Member m = (Member) obj;
	   return (m.getName() == this.name && 
	         m.getGrade() == this.grade && 
	         m.getAddress() == this.address);
	}
}

위와 같이 Member클래스에 equals(), hashCode()메서드를 재정의해준다면 다음과 같이 Set을 이용하여 같은 값을 가진 객체를 중복으로 판단할 수 있다. m1객체와 m2 객체의 해시코드는 필드의 값이 같기 때문에 같은 값을 가진다는 것을 유념하자.

Set 형식이 커스텀 객체를 구분하는 법

public class main {

	public static void main(String[] args) {
		Set<Member> mSet = new HashSet<>();
	    Member m1 = new Member("Jang", "인천", 1);
	    Member m2 = new Member("Jang", "인천", 1);
        Member m3 = new Member("Jang", "인천", 3);
	    Member m4 = new Member("Kang", "서울", 2);
	    
	    mSet.add(m1);
	    mSet.add(m2);
	    mSet.add(m3);
	    mSet.add(m4);
	    
	    Iterator<Member> mI = mSet.iterator();
        System.out.println("Member m2 = new Member(\"Jang\", \"인천\", 1); 중복 제거");
	    while(mI.hasNext()) {
	       System.out.println(mI.next().toString());
	    }
        System.out.println();

        System.out.println("m1 == m2의 결과 '"+ m1 == m2 +"'"); // false    참조하는 메모리 주소 비교
	    System.out.println("m1.eqauls(m2)의 결과 '"+ m1.equals(m2) +"'"); // true       equal로 비교
	    // 저장된 핵심 값이 같기 때문에 같은 해쉬코드를 가짐
	    System.out.println("m1 hashCode: " + m1.hashCode() + "\tm2 hashCode: " + m2.hashCode()); 
	}

}
Member m2 = new Member("Jang", "인천", 1); 중복 제거
이름: Kang	학년:2	주소:서울
이름: Jang	학년:1	주소:인천
이름: Jang	학년:3	주소:인천

m1 == m2의 결과 'false'
m1.eqauls(m2)의 결과 'true'
m1 hashCode: -2081787406	m2 hashCode: -2081787406

결과적으로 Set에서는 다음과 같은 원리로 중복을 제거한다.

  1. Set은 hashCode() 메서드를 이용해서 객체의 해시코드를 확인해서 중복이 있는지 확인한다.
    만약 중복되는 객체가 없다면 Set에 해당 객체를 추가한다.

  2. 만약 중복되는 객체가 있다면 eqauls() 메서드를 이용해서 객체의 중복을 확인한다.
    만약 중복되는 객체가 없다면 해당 객체를 추가한다.

profile
공부한 내용을 적지 말고 이해한 내용을 설명하자
post-custom-banner

0개의 댓글