네이버 카페 코드인에 심심해서 적어 놨던 글을 다시 옮겨옴.
( 워낙 포스팅이 없어서 ;; 요런걸로 때움. ㅋㅋㅋ )
-------
안녕하세요.
 찬 입니다.

우리가 일반적으로 Map이나 HashTable을 쓸때 다음과 같이 사용하지요.

Map map = new HashMap(100);

map.put("찬", new Person( Person.MEN, 29 ) );
map.put("철수", new Person( Person.MEN, 15) );
map.put("영희", new Person( Person.WOMAN , 13 ) );

이때 map에
key로 "찬", "철수", "영희" 와 같이 String을 주고,
value로는 Person 객체를 만들어서 넣어 줍니다.

이때,
map에서는 key 값이 중복되면 기존에 있던 value에다가 새로운 value를 덮어 써 버리게 되는데요.

map.put("찬", new Person( Person.MEN, 29 ) );
map.put("철수", new Person( Person.MEN, 15) );
map.put("영희", new Person( Person.WOMAN , 13 ) );
map.put("철수", new Person( Person.WOMAN, 15 ) ) ;  // 으악! 철수를 여자로 만들어 버렸어!!

put할때에는 key의 hashcode를 보고 쓰게 되어 있죠.
즉, "철수".hashCode() 값이 같기 때문에, 예전에 있던 값에다가 덮어써 버리게 됩니다.
( 정확하게 말하면 Hashtable이나 HashMap에서, 다시 내부적으로 hash하게 되기는 합니다. )


그렇다면 String의 hashCode()에 대해서 좀 알아 봅시다.
아래는 String의 hashCode()에 대한 API문서 내용입니다.

hashCode

public int hashCode()
Returns a hashcode for this string. The hashcode for a String object is computed as
 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)
Overrides:
hashCode in class Object
Returns:
a hash code value for this object.
 

보다시피 String의 hashCode()는 "s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]" 요런 공식에 의해서
값이 반환되게 되어 있는데요, 공식이 무진장 어렵죠. 무슨 말인지도 잘 모르겠고..

공식보다는 hashCode()의 반환값에 대해서 이야기 해 보죠.
hashCode()의 반환값은 int입니다. String 객체의 hashCode()를 가지고 오면 int형태를 반환하게 되죠.


자, 그럼 다시 생각해 봅시다.
int는 총 4byte를 차지할 수 있는 정수형 기본 타입입니다.
4byte로 표현할 수 있는 갯수는 0부터 0xFFFFFFFF(4,294,967,295) 입니다.
즉, hashCode()의 결과는 그 많은 int값 중에서  하나를 반환됩니다.


그렇다면 또 다시 String의 hashCode를 생각해 봅시다.

하지만 String은 무한개를 생성해 낼 수 있습니다. ( "A", "A1",..."AZ", "AA1", "ZZ....ZZZ", "가1A" .... 등등 )
그런데, 이렇게 무한개로 생성해 낼 수 있는 String 객체의 hash code는 int가 반환할 수 있는 숫자중에 하나 입니다.

확률상 서로 다른 String 인데도, 같은 hashcode를 가지는 String이 있을 수 있습니다.


그렇기 때문에,
HashMap이나 Hashtable를 사용할때 아무런 생각없이 String을 key로 주면 안됩니다.
( 생각한다고 해도 마땅한 방법이 없지요. ㅎㅎ. 확률상 극히 낮은 확률이니... ㅎㅎ )
재수가 없으면 데이터가 날아 가는 문제가 발생할 수 있습니다.


그러므로 정말로 반드시 유일한 값이 필요하다고 한다면, hashCode()를 사용해서는 안될것입니다.
char[]을 일일이 가지고 와서 적당히 조작해서 int값으로 만드는 방법을 쓰던지 해야 할것입니다.
( 하지만, 위에서도 말했다시피 - int는 제한적이고 string은 무제한이므로, int를 가지고 어찌할 방법은 없습니다. )

2009년 8월 27일 추가 - 최근에 오래된 글에 대한 코멘트가 많이 달리네요. ㅎ.

지민아빠님의 코멘트처럼, 사실은 hashCode가 같다고 해서 꼭 문제가 되는것은 아닙니다.
이 글에서 이야기 하고 싶은것은,
String.hashCode()는 유일한 값을 반환하지 않는다는 것입니다.
그러므로 아래의 글은 오해할 가능성이 있는 내용을 포함하고 있습니다.


크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 찬

트랙백 보낼 주소 :: http://ggaman.tistory.com/trackback/916 관련글 쓰기

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

  1. 2008/11/19 00:40
    댓글 주소 수정/삭제 댓글
    hashcode 는 같은 값이 나오지만, 그래서 equals 도 같이 사용하는 거잖아요. 내부적으로는 그래서 예비 버킷이 있는.... 흠. 암튼. 유용한 글.. 좋아요. ㅎㅎ
    • 2008/11/19 00:47
      댓글 주소 수정/삭제
      크크. 너무 예리하세요~ ^^
    • 쇼니
      2008/11/19 10:25
      댓글 주소 수정/삭제
      그니깐여..ㅎ
  2. 2009/08/27 12:41
    댓글 주소 수정/삭제 댓글
    해쉬가 같으면 같은 빠겟스에 담는다는거고...
    빠겟스 수는 적절하게 조절되어질테고~

    결론이 좀....ㅋㅋㅋ

    여튼 잘봤음
    • 2009/08/27 13:50
      댓글 주소 수정/삭제
      우왕~
      요즘에 오래된 글에 많은 사람들이 코멘트를 남겨주시네~ ㅎㅎ
      위의 글은 제대로 오해할 소지가 많지~ ㅎㅎ
      하지만, 고치긴 귀찮아. ㅋㅋ

◀ PREV : [1] : ... [45] : [46] : [47] : [48] : [49] : [50] : [51] : [52] : [53] : ... [865] : NEXT ▶

BLOG main image
속성을 알 수 없습니다. by

공지사항

카테고리

분류 전체보기 (865)
잡다한 글들 (199)
여행 (26)
문화생활 (44)
취미 (223)
나의 일 (43)
공부 (226)
재미 (103)
private (1)