2-1(5) Hash() , equals()

zhyun·2020년 9월 16일
0

HighJava

목록 보기
7/67
post-custom-banner

hash funtion

해시 함수(hash funtion)

  • 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑해주는 함수이다.
  • 해시함수에 의해 얻어지는 값은 해시값, 해시코드, 해시체크섬 또는 간단하게 해시라고 한다.

HashSet, HashMap, Hashtable과 같은 객체들을 사용할 경우

  1. 객체가 서로 같은지를 비교하기 위해 equals()메서드와 hashCode()메서드를 호출한다. (Objcet가 갖고있는 메서드 2가지)
  2. 그래서 객체가 서로 같은지 여부를 결정하려면 두 메서드를 재정의 해야 한다.
  3. HashSet, HashMap, Hashtable에서는 객체가 같은지 여부를 데이터를 추가할 때 검사한다.

equals()메서드

  • 두 객체의 내용(값)이 같은지 비교하는 메서드

hashCode()메서드

  • 두 객체가 같은 객체인지를 비교하는 메서드

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

  1. 두 객체가 같으면 반드시 같은 hashcode를 가져야 한다.

  2. 두 객체가 같으면 equals()메서드를 호출했을 때 true를 반환해야 한다. 즉, 객체 a, b가 같다면 a.equals(b)와 b.equals(a) 둘 다 true이어야 한다.

  3. 두 객체의 hashcode가 같다고 해서 두 객체가 반드시 같은 객체는 아니다. 하지만, 두 객체가 같으면 반드시 hashcode가 같아야 한다.

4.equals()메서드를 override하면 반드시 hashCode()메서드도 override해야 한다.

  1. hashCode()는 기본적으로 Heap에 있는 각 객체에 대한 메모리 주소 매핑정보를 기반으로 한 정수 값을 반환한다. int값 반환!!!!

  2. 그러므로, 클래스에서 hashCode()메서드를 override하지 않으면 절대로 두 객체가 같은 것으로 간주 될 수 없다.

  3. hashCode()메서드에서 사용하는 '해시 알고리즘'에서 서로 다른 객체에 대하여 같은 hashcode값을 만들어 낼 수 있다. 그래서 객체가 같지 않더라도 hashCode가 같을 수 있다.
    모리기반으로 되어있기 때문에 적절하게 재정의할 필요성이 있다.

	public static void main(String[] args) {
		//3개의 Person 객체
		Person p1 = new Person(1,"홍길동"); 
		Person p2 = new Person(1,"홍길동"); 
		Person p3 = new Person(1,"이순신");
		
		System.out.println("p1.equals(p2) :"+p1.equals(p2)); 
	        // hashcode() equals() 오버라이드 자동완성 켰을때 true , 껐을때 false
	        System.out.println("p1.equals(p1) :"+p1.equals(p1)); //true
		System.out.println("p1==p2 :"+(p1==p2)); //true
		
		//Person을 담을 HashSet
		Set<Person> set = new HashSet<>();
		//순서가 없고 중복 허용X
		
		set.add(p1);
		set.add(p2);
		
		System.out.println("p1,p2 등록 후 데이터");
		for(Person p:set) {
			System.out.println(p.getId()+":"+p.getName());
			//p1만 등록 p2는 중복체크에 걸려서 추가X => 1:홍길동 
		}
		System.out.println("add(p3) 성공 여부 :"+set.add(p3));//true
		
		System.out.println("p3 등록 후 데이터");
		for(Person p:set) {
			System.out.println(p.getId()+":"+p.getName());
			//1:홍길동 1:이순신
		}
		
		System.out.println("remove(p2) 성공 여부: "+set.remove(p2));//true
		
		System.out.println("remove(p2) 후 데이터");
		for(Person p:set) {
			System.out.println(p.getId()+":"+p.getName()); 
            // p2와 p1과 같은 데이터로 생각 =>1:이순신
		}
	}
}

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;//prime : 소수
		int result = 1;
		result = prime * result + id; // 31+1 = 32
		result = prime * result + ((name == null) ? 0 : name.hashCode()); // 삼항연산자 
		return result;
	}

	@Override
	public boolean equals(Object obj) {// obj:p2
		if (this == obj)//(p1==p1)
			return true;
		if (obj == null)//(p2==null)
			return false;
		if (getClass() != obj.getClass())
        		return false;
               //p1에 대한 getClass p2 Person에 대한 getclass       
		Person other = (Person) obj;//(Person)으로 캐스팅
		if (id != other.id)//내가 갖고 있는 id와 p1의 id와 다를때
			return false;
		if (name == null) { //p1이 null이고
			if (other.name != null) //p2는 null이 아니다
				return false;
		} else if (!name.equals(other.name))//p1의 네임이 p2의 네임과 같지 않으면
			return false;
		return true;
	}
}
profile
HI :)
post-custom-banner

0개의 댓글