2013-05-31 4 views
1

에 동일한 키를 다시 :.<a href="http://docs.oracle.com/javase/6/docs/api/java/util/WeakHashMap.html" rel="nofollow">weakhashmap</a> 자바의 문서에 따르면의 WeakHashMap

"이 클래스는 주로 == 연산자를 사용하여 개체 식별하기위한 방법 시험 동일 키 오브젝트와 함께 사용하도록되어 이러한 키가 삭제되면 WeakHashMap에서 해당 키의 조회를 수행하는 것은 불가능합니다. "

weakhashmap에서 항목 0의 키로 objectA를 사용하고 나중에 해당 항목을 제거하면 testMapHashWeak.remove(objectA); 다른 항목에 동일한 키 objectA을 사용할 수 없습니까? 내가 작은 테스트를 만든 한 원인 내가 할 수

public void test4WeakHashMap(WeakHashMap<B, String> testMapHashWeak) { 
    B objectB = new B(); 
    String sTest = "hola"; 
    System.out.println("1st time - key&value inserted ->"+objectB+","+sTest); 
    testMapHashWeak.put(objectB, sTest); 
    System.out.println("Get element 1st time-> "+testMapHashWeak.get(objectB)); 
    testMapHashWeak.remove(objectB); 
    //Insert 2nd time 
    System.out.println("2st time - key&value inserted ->"+objectB+","+sTest); 
    testMapHashWeak.put(objectB, sTest);   
    System.out.println("Get element 2nd time-> "+testMapHashWeak.get(objectB)); 
} 

는 출력되는 :

1st time - key&value inserted ->[email protected],hola 
Get element 1st time-> hola 
2st time - key&value inserted ->[email protected],hola 
Get element 2nd time-> hola 

답변

1

설명 :이 클래스는 주로 키 오브젝트와 함께 사용하도록되어

는 == 연산자를 사용하여 개체 식별하기위한 방법 시험 같다. 같은 키가 재현 될 수 없다 폐기, 그래서 그것은 불가능하면 는

이 클래스는 휴양 후 (어떤을 생성, 키를 사용하도록 구성되어 있다는 것을 의미의 WeakHashMap에서 해당 키의 조회를 할 수 완전히 똑같은 인스턴스)는 서로 비교할 때 false를 반환합니다. 다른 말로하면, 그러한 키의 새로운 인스턴스는 일의가됩니다 (equals()를 사용해 비교했을 경우는 true가 돌려 주어져 다른 인스턴스/오브젝트와 비교하면 false가 돌려 주어집니다). 는 클래스의 종류는 아니지만 Object

입니다.
WeakHashMap testMapHashWeak = new WeakHashMap<Object, String>(); 

String value1 = "Hola1!"; 
String value2 = "Hola2!"; 

String key1 = new String("key"); 
String key2 = new String("key"); 

assert key1 != key2; // Keys are different objects... 
assert key1.equals(key2); // but are equal to each other 

testMapHashWeak.put(key1, value1); 
testMapHashWeak.put(key2, value2); 

// value2 instead of value1! 
System.out.println("Get using key1 (expected Hola1): "+testMapHashWeak.get(key1)); 
// value2 
System.out.println("Get using key2 (expected Hola2): "+testMapHashWeak.get(key2)); 

Object key3 = new Object(); 
Object key4 = new Object(); 

assert key3 != key4; // Keys are different objects... 
assert !key3.equals(key4); // and are not equal to each other 

testMapHashWeak.put(key3, value1); 
testMapHashWeak.put(key4, value2); 

// value2 instead of value1! 
System.out.println("Get using key3 (expected Hola1):"+testMapHashWeak.get(key3)); // value1! 
// value2 
System.out.println("Get using key4 (expected Hola2):"+testMapHashWeak.get(key4)); 

WeakHashMap은 취약한 키가있는지도의 구현입니다. 따라서 키가 가비지 수집 된 후지도의 전체 항목 (키, 값)이 사라집니다. 그렇다면 여기서 핵심 단어는 "사후"입니다. 그래서 키 사이에는 'GC에 의해 삭제됨'으로 표시되고 실제로 삭제되기 전에는 얻을 수없는 키 - 값 항목이 맵에 포함됩니다. 문자열 기반 키를 사용하는 첫 번째 예제에서는 다른 키를 사용하여 값을 가져올 수 있지만 값이 있는지 여부를 예측할 수 없습니다 (이미 GCd 일 수 있음). 두 번째 예제에서는 어떠한 경우에도 사용할 수 없습니다.

+0

귀하의 진술은 정확하지만 귀하의 예는 아닙니다.문제는 문자열 상수''key "'*를 포함하고있는 key1과 key2가 동일한 인스턴스 (assertions를 사용하면 좋다, 어설 션을 활성화 한 코드를 실행하는 것이 더 좋다)이다. Java는 동일한 객체 인스턴스를 사용하여 컴파일 타임 상수 문자열을 나타냅니다. 그 중 하나를'new String ("key")로 바꾸면 서로 다른 String 인스턴스가 동일한 상황을 만들 수 있습니다. – Holger

+0

수정 제안을 편집 한 코드 예제입니다. – Holger

+0

원본 코드가 손상되었지만 편집이 거부되었습니다. 제안 된 수정이 원래의 의도를 유지함에 따라 그 이유를 이해할 수 없습니다. 그러나 사실, 첫 번째 어설 션이 실패한 것 외에도 key3 및 key4 객체를 만든 후 어설 션은 key1 및 key2 대신에 이들을 참조해야합니다. 원래 포스터 만이 해당 코드를 수정할 수 있습니다. – Holger

1

그 문장에서 "폐기"는 "키 객체가 일반적인 사용에서 더 이상"을 의미하지 더 이상 라이브 오브젝트가 아닙니다. test4WeakHashMap 방법의 전체 범위에서 사용중인 objectB의 경우에는 해당되지 않습니다. 같은 문서에서

:

의 키가 더 이상 일반 사용 때의 WeakHashMap의 항목이 자동으로 제거되지 않습니다. 보다 정확하게는, 주어진 키에 대한 매핑이 존재하더라도 키가 가비지 컬렉터에 의해 폐기되는 것을 막을 수는 없습니다. 즉, 최종화가 가능하고 마무리되고 다시 회수됩니다. 키가 파기되었을 때, 그 엔트리는 맵으로부터 효과적으로 삭제되기 (위해) 때문에,이 클래스는 다른 Map 구현과 다소 다른 동작을합니다.

"가비지 수집기에서 삭제됨"에 유의하십시오. 따라서 "지도에서 제거"는 "폐기"와 동일하지 않습니다.