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에서는 다음과 같은 원리로 중복을 제거한다.
Set은 hashCode() 메서드를 이용해서 객체의 해시코드를 확인해서 중복이 있는지 확인한다.
만약 중복되는 객체가 없다면 Set에 해당 객체를 추가한다.
만약 중복되는 객체가 있다면 eqauls() 메서드를 이용해서 객체의 중복을 확인한다.
만약 중복되는 객체가 없다면 해당 객체를 추가한다.