JAVA-equals(), hashCode()

정서윤·2021년 6월 29일
0

JAVA

목록 보기
4/10

Hash Function

해시 함수(hash function)는 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수이다.
해시함수로 얻어지는 값은 해시값, 해시코드, 해시 체크섬 또는 간단하게 해시라고 부른다.

해싱을 사용하면 검색이 빠르다.

HashSet, HashMap, Hashtable 같은 객체들을 사용 할 경우 객체가 서로 같은지 비교하기 위해 equals()와 hashCode()메서드를 호출한다.
그래서 객체가 서로 같은지 결정하려면 두 메서드를 재정의 해야한다.

HashSet, HashMap, Hashtable에서는 객체가 같은지 여부는 데이터를 추가 할 때 검사한다.

-equals() 메서드는 두 객체의 내용(값)이 같은지 비교하는 메서드이고,
-hashCode() 메서드는 두 객체가 다른 객체인지(다른 해쉬코드를 갖고있는지) 비교하는 메서드이다. (Hash 붙은 것들만 사용. 다른것은 equals만 쓰면 알 수 있음)

equals()와 hashCode()메서드에 관련된 규칙

1.두 객체가 같으면 반드시 같은 hashCode를 가져야한다.
2.두 객체가 같으면 equals()를 호출했을 때 true를 반환해야 한다.
즉, 객체 a와 객체 b가 같다면 a.equlas(b)와 b.equals(a) 둘 다 true 여야 한다. //객체 a와 객체b의 이름이 같아서 같은 객체 취급 하고 싶을 때
3.두 객체의 hashCode가 같다고 해서 두 객체가 반드시 같은 객체인 것은 아니다. //리턴타입이 int이므로 아주 가끔 다른 객체여도 같은 정수를 리턴할 수도 있다는 뜻. = 해쉬함수의 충돌성(한계)
하지만, 두 객체가 같을 땐 반드시 hashCode가 같아야 한다.
4.equals() 메서드를 override하면 반드시 hashCode()메서드도 override해야 한다.
5.hashCode()는 기본적으로 Heap에 있는 각 객체에 대한 메모리 주소 매핑정보를 기반으로 한 정수값을 반환한다.//hashcode()는 int 타입을 리턴.
그러므로 클래스에서 hashCode() 메서드를 override하지 않으면 두 객체가 같은 것으로 간주 될 수 없다.

  • hashCode() 에서 사용하는 '해싱 알고리즘'에서 서로 다른 객체에 대하여 같은 hashcode를 만들어 낼 수 있다.
    그래서 객체가 같지 않더라도 hashcode가 같을 수 있다.
  • new로 새로운 객체를 생성하면 각 객체는 hashcode가 다르다(메모리 주소가 다르니까)
public static void main(String[] args) {
		Person p1 = new Person(1,"홍길동");
		Person p2 = new Person(1,"홍길동");
		Person p3 = new Person(1,"이순신");
		
		System.out.println("p1.equals(p2) : " +p1.equals(p2));	//Object의 equals = 메모리주소 기반 비교라서 false
		System.out.println("p1 == p2 : " + (p1 == p2));			//근데 나는 값(아이디랑 이름)이 같으면 같은 객체취급 하고 싶으니까 equals 메서드 오버라이딩하자.
		System.out.println();
		
		Set<Person> set = new HashSet<>();
		
		set.add(p1);
		set.add(p2);
		
		System.out.println("p1, p2 등록 후 데이터 : ");
				for(Person p : set) {
					System.out.println(p.getId() + " : " + p.getName());
				}
				System.out.println("add(p3) 성공여부 : " +set.add(p3));
				
				System.out.println("add(pe) 후 데이터 ");
				for(Person p : set) {
					System.out.println(p.getId() + " : " + p.getName());
				}
				
				System.out.println("remove(p2) 성공 여부 : " +set.remove(p2));
				System.out.println("remove(p2) 후 데이터");
				for(Person p : set) {
					System.out.println(p.getId() + " : " + p.getName());
				}
	}

}


	class Person {
		
		@Override
		public String toString() {
			return "Person [id=" + id + ", 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;
		}
		
		//id랑 name 값이 같으면 같은 객체 취급 하자고 equals 메서드 오버라이딩
		//하지만 이것만으로는 같은 객체 취급X 해쉬코드는 다르니까.
		@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;
		}




		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;
		}
		public Person(int id, String name) {
			super();
			this.id = id;
			this.name = name;
		}
		
		private int id;
		private String name;
		
	}
profile
차근차근

0개의 댓글

관련 채용 정보