일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- .net
- 명시적외래키
- EFCore
- LINQ
- vscode
- JSON
- mac
- 대전본식영상
- dbContext
- 라도무스dvd
- scanner
- Request
- error
- React
- 스냅잘찍음
- ViewModel
- 상속
- Store
- intellij
- lazy loading
- ORM
- c#코딩의기술실전편
- extjs
- extraParams
- c#
- JavaScript
- 에스가든스냅
- Config
- minimalAPI
- 코드프로그래머스
- Today
- Total
ejyoo's 개발 노트
Hash - equals()와 hash() 메서드 구현 본문
ejyoo.tistory.com/72?category=930353
지난 포스팅에서 Hash에 대한 포스팅을 올린 이력이 있다.
본 포스트는 테스트 코드만 작성한다.
💡 객체 클래스화 후 객체 값 비교
public class Main {
public static void main(String[] args) {
Person p1 = new Person(1, "홍길동");
Person p2 = new Person(1, "홍길동");
System.out.println("p1.equals(p2) : " + p1.equals(p2));
}
}
class Person{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person p1 과 Person p2 는 우리가 보기엔 같은 값이 들어있다.
하지만 그 결과값은 true 가 아닌 false 가 나온다.
이 이유는 equals와 hashCode를 오버라이드 하지 않고
Object 의 equals를 사용하여 멤버를 비교하였기 때문에 false가 나온것이다.
Object에 정의된 equals를 사용하는 경우, 생성한 객체에 대해 값이 같은지 비교할 수 없다.
이에 대한 해결방법은
Object에 구현된 메서드를 오버라이드 하여 Object에 구현된 equals, hashCode 메서드를 사용하지 않고 새로운 형태를 사용한다.
equals와 hashCode 메서드를 오버라이드 해보자.
💡 오버라이드 구현(equals, hashCode)
이클립스 자동완성 기능을 활용하여 만든다.
public class Main {
public static void main(String[] args) {
Person p1 = new Person(1, "홍길동");
Person p2 = new Person(1, "홍길동");
System.out.println("p1.equals(p2) : " + p1.equals(p2));
}
}
class Person{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;//소수 : 1과 자기자신으로만 나눌 수 있는 것.
int result = 1;
result = prime * result + id;//객체의 id 값
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)//this : p1 = p1넣은 경우 (this.p1.equals(object))
return true;
if (obj == null)//p1.equals(null)
return false;
// getClass() : Object가 속한 클래스정보를 가져옴
// Object를 만들라면 Class가 존재해야된다. 클래스 없이 Object를 만들 수 없다.
if (getClass() != obj.getClass())//getClass() : Person , obj.getClass() : Person
return false;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
위의 코드를 살펴본다.
오버라이드 된 hashCode에서
final int prime = 31;
이부분은, 해시코드는 기본적으로 임의의 소수로 설정한다.
오버라이드 시 소수 31을 사용하여 구현한다.
나머지는 코드 그대로 해석하면 된다.
이상태에서 다시 실행을 해본다.
결과값이 True가 됨을 확인할 수 있다.
p1과 p2를 equals가 아닌 비교연산자 '=='를 사용한 경우 아래와 같이 표시된다.
public class Main {
public static void main(String[] args) {
Person p1 = new Person(1, "홍길동");
Person p2 = new Person(1, "홍길동");
System.out.println("p1.equals(p2) : " + p1.equals(p2));
System.out.println("p1 == p1 : " + (p1==p1));
System.out.println("p1 == p2 : " + (p1==p2));
}
}
class Person{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
💡 Set에 객체 저장해보기
중복 저장이 되지 않는 Set을 사용하여 생성한 Person 객체를 넣어본다.
equals와 hashCode를 오버라이드하여 구현했기 때문에
구현한 객체에 대한 비교를 할 수 있는 상태이므로
위의 코드에서 같다고 나온 p1, p2 객체가 Set에 들어갔을 때,
최초 삽입됐던 p1 객체만 들어가게 되고 p2 객체는 중복으로 인하여 삽입이 취소된다.
아래의 코드를 확인해본다.
package baekjoonProject;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Person p1 = new Person(1, "홍길동");
Person p2 = new Person(1, "홍길동");
System.out.println("p1.equals(p2) : " + p1.equals(p2));
System.out.println("p1 == p1 : " + (p1==p1));
System.out.println("p1 == p2 : " + (p1==p2));
System.out.println("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");
Set<Person> set = new HashSet<Person>();
System.out.println("set.add(p1) 성공 여부 : " + set.add(p1));
System.out.println("set.add(p2) 성공 여부 : " + set.add(p2));
}
}
class Person{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
Set에 p2는 add() 실패한 것을 확인할 수 있다. set 변수의 사이즈와 데이터를 찍어본다.
아래 코드를 추가한다.
System.out.println("set의 size() : " + set.size());
System.out.println("set의 내용");
for(Person p : set) {
System.out.println(p.getId() + " : " + p.getName());
}
'BackEnd > Java' 카테고리의 다른 글
Properties (0) | 2021.03.08 |
---|---|
Map (0) | 2021.03.08 |
TreeSet (0) | 2021.03.07 |
Set (0) | 2021.03.07 |
List의 정렬(Sort) - interface : Comparable, Comparator (3) (0) | 2021.03.06 |