2009-12-09 3 views
4

여기에 나의 사용 사례가 있는데, 논리적으로 내 HashMap 키와 같지만 같은 개체가 아닌 (==가 아닌) 개체가 있습니다. HashMap에서 Actall Key 객체를 가져와 동기화 할 수 있어야합니다. 나는 ketSet을 반복 할 수 있다는 것을 알고 있지만 이것은 해시에 비해 느리다.getEntry (Object key)가 HashMap에 노출되지 않는 이유는 무엇입니까?

java.util.HashMap 구현을 살펴보면 필자가 필요로하는 getEntry (Object key) 메소드를 볼 수 있습니다. 왜 이것이 노출되지 않았는가?

키를 얻을 수있는 다른 방법이 있습니까?

+0

당신은 반사에 의해 그것을 얻을 수 있고, 다른 방법이 없다면 여전히 사용합니다. – Geo

+0

논리적으로 같음 = 같음 메서드를 덮어 썼습니까? HashMap은 항상 ==가 아닌 equals를 사용합니다. 변경 가능한 개체를 키 클래스로 사용하는 것은 일반적으로 권장되지 않습니다. – dmeister

+0

@ Geo : 나는 리플렉션을 사용하여 동기화 할 객체를 얻는 것에 대해 모호합니다. 부분적으로는 성능 문제가 있지만 주로 상수가 아닌 객체에 대한 명시 적 동기화가 어쨌든 어려울 수 있으므로 리플렉션을 통해 해당 참조를 불투명하게 얻을 때 신경 쓰지 마세요. 유지 보수를 악몽으로 만드는 것은 이해하기 쉽고, 디버깅하기가 쉽지 않습니다. –

답변

4

값에 간접 지정의 추가 레이어를 넣는 것이 나을 것이라고 생각합니다. 키는 "순수한"값이어야합니다. 대신 :

Map<ReferenceObjectKey,Thing> map; 

사용 :

Map<ValueObjectKey,ReferenceObject<Thing>> map; 
+0

예를 들어, 'String' 키는 여전히 위에서 선언 한 동일한 문제를 일으킬 수 있습니다 (예 : '인턴은 나쁜 생각 인 모든 Strings); 누군가가 문자열이 부적절한지도 키라고 말하는 것을 들어 본 적이 없습니다. –

+0

나는 따라 가지 않는다. 'String'은 제 책의 값 객체입니다. –

+0

문자열과 다른 값 개체에 문제가 여전히 존재한다고 말하고 있습니다. 당신이 제안한 해결책은 문제를 해결하지 못할 것입니다. (querent가 제기 한 문제는 해결할 필요가 없다는 사실을 제외하고). –

0

이것은 당신이 물고있는 더 깊은 문제와 같습니다. 왜 그런게 필요한거야? 왜 그 열쇠는 그 물건에 고유하지 않습니까?

"이걸 내가 동기화 할 수 있어요"라는게 무슨 뜻이야?

+0

내가 원하는 것은 동일한 객체 (즉, 해시 맵 내에서 동일한 키 *에 매핑 됨)를 모두 호출해야한다는 것입니다. 동기화를 위해 일관된 객체 장애물에 액세스하십시오. querent는 왜 이것이 원하는지는 말하지 않았지만 두 개의 스레드가 주어진 키에 대한 매핑을 한 번에 수정할 수 없도록하려는 시도처럼 들립니다. –

+0

당신이 옳다고 생각합니다. 문제에 대한 가정이 맞다면 ConcurrentHashMap을 사용하여 문제를 해결할 수 있습니다 :) –

3

저자가 공개하지 않기로 결정했기 때문에 실제 질문에 대답 할 수 없습니다 (이 방법이 노출되지 않는 이유는 무엇입니까?).

그러나 귀하의 질문에 따라 귀하는 다소 이상한 동기화 계획이 있다고 생각합니다. 내 이해에서 당신은 동기화를 위해 동등한 객체의 정식 표현을 얻기 위해 그것을 호출하려고 시도하고 있습니다. 제가 그 질문에 대한 제 의견에 언급했듯이, 이것은 정말로 나쁜 생각처럼 들립니다.

더 나은 접근 방법은 이러한 주요 개체를 동기화하는 방법과 이유를 다시 생각해보고 동기화를보다 명확하고 높은 수준으로, 또는 다른 방법을 사용하여보다 명확하고 더 건전하게 재 작업하는 것입니다.

다른 사용자가 자신의 의견을보다 명확하게 구현할 수 있도록이 동기화 작업을 수행하려는 코드 스 니펫을 게시하면 도움이 될 수 있습니다. 여기에 실제로 달성하려는 경우 실제로는 스레드 안전 맵 클래스 (예 : ConcurrentHashMap)를 사용하는 것이 좋습니다.

편집 : How To Ask Questions The Smart Way을보고, 특히 이것이 결점의 고전적인 예입니다. 당신의 전반적인 디자인이 약간 떨어져서 다른 방향으로 나아갈 필요가있을 것 같습니다; 그래서이 특정 문제에 얽매이지 만 큰 문제의 증상입니다. 우리에게보다 폭 넓은 맥락을 제공하면 전반적인 답변이 훨씬 더 잘 전달됩니다.

-1

미안하지만, 당신이 여기 개념 휴식을 갖고있는 것 같다.

등가의 객체 (. equals()가 true이지만 ==가 false)를 키에 저장하고 get을 Object variant로 사용하면 키를 찾아야하는 경우 문제가 해결되지 않으면 왜냐하면 Object가 지원하는 유일한 equals는 identity (==)이기 때문입니다.

당신이해야 할 일은 키 클래스에 equals()와 물론 hashcode()를 구현하는 것입니다.

이렇게하면 항목을 얻는 것이 쉽습니다.

+0

물론 equals와 hashcode를 구현했습니다. 제 질문은 –

2

사실, 호출자가 요구하는 방법이 유용했을 것입니다. 틀림없이 실수 나 그와 같은 것이 포함되지 않았다.

키 "a"에서 매핑 된 Integer 값을 증가시키려는 경우 "a"에 대해 해시 검색을 두 번 수행해야합니다. 존재하지 않는 값과 존재하지만 존재하지 않는 값을 구별하기를 원한다면 - 다시 두 개의 해시 검색을합니다.

실제로이 때문에 세계는 끝나지 않았습니다.

1

나는 최근에이 문제에 최근에 비틀 거렸다. 문제를 충분히 끓일 때, 본질적으로 평등을 결정하는 데 사용 된 핵심 객체의 부분과 데이터를 연결하는 두 가지 방법을 사용하고있었습니다. 키 매핑 값으로

  • 키 오브젝트에 포함 된 데이터와 맵을 통해
  • 있지만 그 조성물로 상기 .equals()/해시 코드 방식에서 사용되지 않았다.

키 클래스의 List를 사용하여 동등성과 해시 코드를 확인했으며 그 밖에도 3 개의 다른 입력란 (부울 및 2 개의 입력란)이있었습니다. 마지막으로 Map을 Map < List < String>, ...>으로 다시 작성하고 다른 3 개의 필드를 자체 클래스로 리팩터링 한 다음 원래 클래스를 List 및 새 클래스의 구성으로 사용했습니다. 나는 그 후 코드가 나아 졌다고 느꼈다.

관련 문제