2012-04-30 1 views
27

안녕하세요 저는 이름/나이 (문자열/정수) 쌍을 포함하는 LinkedHashMap (정보)가 있습니다. 나는 키를 입력하면 키/값의 위치를 ​​어떻게 얻을 수 있는지 알고 싶다. 예를 들어 LinkedHashMap이 {bob = 12, jeremy = 42, carly = 21}처럼 보이면 jeremy를 검색하려고 했으므로 위치 1로 1을 반환해야합니다. info.getIndex와 같은 것을 사용할 수 있기를 바랬습니다. ("jeremy")키를 사용하여 LinkedHashMap에서 키/값의 위치를 ​​얻는 방법

+1

[이유 -ndnt-linkedhashmap-provide-index-by-access]를 참조하십시오. (http://stackoverflow.com/questions/5666820/why-doesnt-linkedhashmap-provide-access-by-index) – nawfal

답변

22

HashMap 구현은 일반적으로 Iteration에 대해 순서가 지정되지 않습니다.

LinkedHashMap은 아주 인 - 인, predictablely이 Iteration (삽입 순서)에 대한 주문 하지만 중 인덱스 위치 자체를 추적하지 않는 List 인터페이스와 LinkedList (키 세트 삽입 순서를 반영 무엇을) 노출하지 않습니다 효율적으로 색인을 찾을 수 있습니다. LinkedHashMapLinkedList 내부 참조를 노출하지 않습니다.

실제 "연결된 목록" 동작은 구현에 따라 다릅니다. 일부 은 실제로 LinkedList의 인스턴스를 사용할 수도 있습니다. 그 중 일부는 단지 Entry 이전과 다음을 모두 추적하고 을 추적하고이를 구현으로 사용하십시오. 출처를 보지 않고 아무 것도하지 마십시오.

때문에 상속 HashMap의 백업 데이터 구조 배치에 사용되는 해싱 알고리즘뿐만 아니라 순서를 보장하지 않는 키를 포함하는 KeySet

. 그래서 당신은 그것을 사용할 수 없습니다.

직접 구현하지 않고이 작업을 수행하는 유일한 방법은 미러링 LinkedList을 사용하는 Iterator을 걷고 현재 위치를 유지하는 것입니다.이 방법은 대용량 데이터 세트에서 매우 효율적입니다.

솔루션 당신이 원하는 것처럼 들리

원래 삽입 순서 인덱스 위치, 당신은, ArrayList 같은에서 KeySet의 키를 반영해야하는 업데이트와 동기화를 유지하는 것 HashMap을 찾아 위치 찾기에 사용하십시오. HashMap의 하위 클래스를 만들고 IndexedHashMap라고 말하고 내부적으로이 ArrayList을 추가하고 ArrayList.indexOf()에 위임하는 .getKeyIndex(<K> key)을 추가하는 것이 아마도 가장 좋은 방법 일 것입니다.

LinkedHashMapLinkedList이고, ArrayList 대신 KeySet이 반영됩니다.

+1

LinkedHashMap 명령을 유지합니다. 키/값을 저장할 수 있지만 주문을 유지하는 데 사용할 수있는 것이 있습니까? – Matt9Atkins

+1

* 주문 *을 유지하지만 * 위치는 추적하지 않습니다. –

+0

@ HernánEche는 질문과 답변을 읽고 이해했으며, 자세를 추적하기를 원합니다. 이에 대한 자세한 내용은 제 대답을 참조하십시오. –

0

LinkedHashMap에 "예측 가능한 반복 순서"(javadoc)가 있습니다. 항목은 위치를 알지 못하므로 가져 오기 위해 컬렉션을 반복해야합니다. 큰지도를 관리하는 경우 저장을 위해 다른 구조를 사용하는 것이 좋습니다.

편집 : 당신은 구글 구아바 라이브러리에서 com.google.common.collect.LinkedListMultimap을 사용할 수 있습니다

+0

* "'Set '키를 걷는 것은 좋은 일이 아니며'Set '에 의해 뒷받침되며 순서가 없습니다.'LinkedList '는'Iterator '에서만 사용됩니다 [의심스러운 경우 소스를 사용하십시오] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashMap.java#HashMap.keySet%28%29). –

+0

사실 엔트리 집합을 의미 했으므로 반복 순서 비트를 인용 한 이유는 ... 반복자 사용을 암시하는 것입니다. 내 부분의 단어 선택이 잘못되었습니다 –

+0

javadoc의 첫 번째 단락에 삽입 순서가 지정되어 있습니다. 어쨌든, 우리가 여기서 같은 말을하고있는 것 같아요. 편집 결과가 답을 더 분명하게 만들었습니다. –

0

반복을 명확히.이 클래스의 멀티 맵 동작이 필요하지 않다는 것은 keys() 메서드가 삽입 순서로 반환되어 List를 생성하는 데 사용할 수 있다는 것을 의미합니다. 을 사용하여 필요한 인덱스 위치를 찾을 수 있습니다.

9
int pos = new ArrayList<String>(info.keySet()).indexOf("jeremy") 
+1

Afaik는'keySet()'명령을 사용합니다. 보장되지 않습니다. – membersound