자바의 정석 ( hashCode() / toString() )

류경호 ㅣ 2023. 4. 6. 17:57

hashcCde()

객체의 주소를 int값으로 변환한다.

equals를 오버라이딩하여 객체의 값을 비교할 때 hashCode(객체의 주소)도 동일하게 오버라이딩 해주어야한다. 

=> 같은 객체라면 hashCode메서드를 호출했을 때의 결과값인 해시코드도 같아야하기 때문.

hashCode를 오버라이딩 하지 않는다면 Object클래스에 정의된 대로 모든 객체가 서로 다른 해시코드값을 가지게 된다. 

 

 

public class Ex_9_3 {

	public static void main(String[] args) {

		String str1 = new String("abc");
		String str2 = new String("abc");
		
		System.out.println(str1.equals(str2));
		System.out.println(str1.hashCode());
		System.out.println(str2.hashCode());
		System.out.println(System.identityHashCode(str1));
		System.out.println(System.identityHashCode(str2));
	}
}
-------------------------------------------------------------
결과
true
96354
96354
27134973
1284693
-------------------------------------------------------------
String클래스는 문자열의 내용이 같으면 동일한 해쉬코드를 반환하도록 오버라이딩 되어있다.
따라서 str1과 str2의 해시코드값은 같다.
반면에 System.identityHashCode(Object x)는 Object클래스의 hashCode메서드 처럼
객체의 주소값으로 해시코드를 생성하기 때문에 객체마다의 해시코드값이 다르게 나온다.

 

 

toString()

이 메서드는 인스턴스의 정보를 제공하는 것으로 Object클래스에 정의된 tiString()는 다음과 같다,

public String toSting() {

return getClass().getName()+"@"+Integer.toHexString(hashCode())

}

클래스를 작성할 때 toString()을 오버라이딩 하지않는다면 다음 예시와 같다.

 

class Card {
	String kind;
	int number;
	
	Card() {
		this("SPADE", 1);
	}
	
	Card(String kind, int number) {
		this.kind = kind;
		this.number = number;
	}
}

public class Ex_9_4 {

	public static void main(String[] args) {
		Card c1 = new Card();
		Card c2 = new Card();
		
		System.out.println(c1.toString());
		System.out.println(c2.toString());
	}
}
------------------------------------------------
결과
Card@2a139a55
Card@15db9742
------------------------------------------------
toString를 오버라이딩 하지않아서 클래스이름과 해시코드가 출력되었다.

 

 

String클래스의 toString은 String인스턴스가 갖고 있는 문자열을 반환하도록 오버라이딩 되어있고

Date클래스의 경우, Date인스턴스가 갖고 있는 날짜와 시간을 문자열로 변환하도록 오버라이딩 되어있다.

이처럼 toString()은 일반적으로 문자열로 변환하여 정보를 얻도록 오버라이딩이 되어 있다.

다음은 Card클래스에서도 toString()을 오버라이딩하여 보다 쓸모있는 정보를 제공하도록 만들었다.

class Card {
	String kind;
	int number;
	
	Card() {
		this("SPADE", 1);
	}
	
	Card(String kind, int number) {
		this.kind = kind;
		this.number = number;
	}
	
	public String toString() {
		return "kind : " + kind + ", number : " + number; // 오버라이딩
	}
}

public class Ex_9 {

	public static void main(String[] args) {
		Card c1 = new Card();
		Card c2 = new Card("HEART", 10);
		System.out.println(c1.toString());
		System.out.println(c2.toString());
	}
}
-------------------------------------------------------------
결과
kind : SPADE, number : 1
kind : HEART, number : 10