네이버 카페 코드인에 심심해서 적어 놨던 글을 다시 옮겨옴.
( 워낙 포스팅이 없어서 ;; 요런걸로 때움. ㅋㅋㅋ )
-------
안녕하세요.
찬 입니다.
우리가 일반적으로 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
Stringobject is computed ass[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
usingintarithmetic, wheres[i]is the ith character of the string,nis the length of the string, and^indicates exponentiation. (The hash value of the empty string is zero.)- 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를 가지고 어찌할 방법은 없습니다. )
지민아빠님의 코멘트처럼, 사실은 hashCode가 같다고 해서 꼭 문제가 되는것은 아닙니다.
이 글에서 이야기 하고 싶은것은,
String.hashCode()는 유일한 값을 반환하지 않는다는 것입니다.
그러므로 아래의 글은 오해할 가능성이 있는 내용을 포함하고 있습니다.
'공부 > Java' 카테고리의 다른 글
| [Java/Tip] String.intern()은 메모리를 아낄 수 있다? (8) | 2008/11/25 |
|---|---|
| [Java/Tip] Hashtable을 제대로 활용하지 못하는 경우... (8) | 2008/11/20 |
| [Java/Tip] String.hashCode()는 유일한 값을 반환할까? (5) | 2008/11/18 |
| [Java/Tip] Specifc Debugging Tips for Swing - 4.2.1 Incorrect Threading (2) | 2008/11/05 |
| Java char로 어떻게 16bit 이상의 문자를 표현할 수 있을까? (0) | 2007/07/25 |
| Java의 Windows FileOutputStream 은 안전하지 않다.. (4) | 2007/01/12 |