위치로 HashMap에서 요소를 가져올 수 있습니까?


99

위치별로 HashMap에서 요소를 검색하는 방법은 무엇입니까?


11
"위치"란 무엇을 의미합니까? HashMaps는 순서가 지정되지 않았으므로 벡터와 같은 것으로 얻을 수있는 일반적인 "위치"개념이 없습니다.
Mat 2011 년

1
게재 신청서 또는 다른 주문을 의미합니까?
Mark Elliot 2011 년

답변:


94

HashMaps 는 순서를 유지하지 않습니다.

이 클래스는지도의 순서를 보장하지 않습니다. 특히 주문이 시간이 지나도 일정하게 유지된다는 보장은 없습니다.

예측 가능한 반복 순서를 보장하는 LinkedHashMap을 살펴보십시오 .


16
이것은 실제로 질문에 대한 답이 아닙니다. 아래의 다른 답변이 더 유용합니다.
forresthopkinsa

6
존경심으로, 이것은 질문에 직접 답하는 문서를 인용합니다
Wayne

1
시간이 지남에 따라 순서가 일정하지 않더라도 주어진 위치에 따라 멤버 중 하나를 검색 할 수 있습니다.
초급

나는 따르지 않는다. 설명?
Wayne

HashMap 링크가 깨졌습니다 / 404.
Raf

109

LinkedHashMap을 사용하고 위치별로 검색해야하는 경우 값을 ArrayList로 변환합니다.

LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<String,String>();
/* Populate */
linkedHashMap.put("key0","value0");
linkedHashMap.put("key1","value1");
linkedHashMap.put("key2","value2");
/* Get by position */
int pos = 1;
String value = (new ArrayList<String>(linkedHashMap.values())).get(pos);

2
HashMap에서 키 복사본을 인스턴스화하려면 항상 필요합니까 ??
Richard

이렇게하면 값을 검색 할 때마다 새 ArrayList 개체가 생성되어 메모리 누수가 발생합니다
NullByte08

48

당신은 당신이지도 사용에 요소를 추가하는 순서 유지하려면 LinkedHashMap단지 반대를 HashMap.

다음은 맵의 인덱스로 값을 가져올 수있는 접근 방식입니다.

public Object getElementByIndex(LinkedHashMap map,int index){
    return map.get( (map.keySet().toArray())[ index ] );
}

1
내가 말해야 할 가장 간단한 말은 ... 모든 것을 변환하는 대신 키셋 만 사용하는 것입니다. 뛰어난
kirtan403

19

어떤 이유로 hashMap을 고수해야하는 경우 keySet을 배열로 변환하고 배열의 키를 인덱싱하여 다음과 같이 맵에서 값을 가져올 수 있습니다.

Object[] keys = map.keySet().toArray();

그런 다음 다음과 같이지도에 액세스 할 수 있습니다.

map.get(keys[i]);

그 편곡 참고 [I]은 변경해야합니다 키 [I]
모흐센 Abasi

좋아, 나는 그들 중 하나를 얻기 위해 맵 키로 문자열을 가지고 있습니다. 두 번째 부분은 다음과 같습니다.String myKey = keys[i].toString();
Orici

12

사용 LinkedHashMap:

예측 가능한 반복 순서와 함께 Map 인터페이스의 해시 테이블 및 연결 목록 구현. 이 구현은 모든 항목을 통해 실행되는 이중 링크 목록을 유지한다는 점에서 HashMap과 다릅니다.


27
순서는 유지되지만 색인으로 항목에 액세스 할 수는 없습니다. 반복해야합니다
Bozho 2011 년

이 링크는 이전 버전의 API에 대한 것입니다. Java 6 또는 7 API에 연결하는 것이 좋습니다.
jzd 2011 년

6

LinkedHashMap을 사용하고이 함수를 사용하십시오.

private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();

이렇게 정의하고.

private Entry getEntry(int id){
        Iterator iterator = map.entrySet().iterator();
        int n = 0;
        while(iterator.hasNext()){
            Entry entry = (Entry) iterator.next();
            if(n == id){
                return entry;
            }
            n ++;
        }
        return null;
    }

이 함수는 선택한 항목을 반환 할 수 있습니다.


3

나는 '위치'로 HashMap에 요소를 삽입 한 순서를 참조한다고 가정하고 있습니다. 이 경우 LinkedHashMap을 사용하고 싶습니다. LinkedHashMap은 접근 자 메소드를 제공하지 않습니다. 다음과 같이 작성해야합니다.

public Object getElementAt(LinkedHashMap map, int index) {
    for (Map.Entry entry : map.entrySet()) {
        if (index-- == 0) {
            return entry.value();
        }
    }
    return null;
}

3

또 다른 작업 방법은 맵 값을 배열로 변환 한 다음 인덱스에서 요소를 검색하는 것입니다. LinkedHashMap에서 다음 접근 방식을 사용하여 100,000 개의 개체에 대한 인덱스 검색을 통해 100,000 개의 요소를 테스트하면 다음과 같은 결과가 나타납니다.

//My answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
    return map.values().toArray(new Particle[map.values().size()])[index];
} //68 965 ms

//Syd Lambert's answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
    return map.get( (map.keySet().toArray())[ index ] );
} //80 700 ms

LinkedHashMap에서 인덱스로 요소를 검색하는 것은 모두 상당히 무거운 작업 인 것 같습니다.


2

HashMap-및 기본 데이터 구조-해시 테이블에는 위치 개념이 없습니다. LinkedList 또는 Vector와 달리 입력 키는 값이 저장되는 '버킷'으로 변환됩니다. 이러한 버킷은 HashMap 인터페이스 외부에서 의미가있는 방식으로 정렬되지 않았으므로 HashMap에 입력 한 항목은 다른 데이터 구조에서 예상하는 순서가 아닙니다.


2

HashMap에는 위치 개념이 없으므로 위치별로 객체를 가져올 방법이 없습니다. 지도의 개체는 키로 설정되고 가져옵니다.


2

아래 코드를 사용하여 키를 얻을 수 있습니다. String [] keys = (String[]) item.keySet().toArray(new String[0]);

다음과 같이이 항목의 키로 HashMap에 삽입되는 객체 또는 목록을 가져옵니다. item.get(keys[position]);


2

기본적으로 java LinkedHasMap은 위치 별 값 가져 오기를 지원하지 않습니다. 그래서 나는 맞춤형으로 이동하는 것이 좋습니다.IndexedLinkedHashMap

public class IndexedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    private ArrayList<K> keysList = new ArrayList<>();

    public void add(K key, V val) {
        super.put(key, val);
        keysList.add(key);
    }

    public void update(K key, V val) {
        super.put(key, val);
    }

    public void removeItemByKey(K key) {
        super.remove(key);
        keysList.remove(key);
    }

    public void removeItemByIndex(int index) {
        super.remove(keysList.get(index));
        keysList.remove(index);
    }

    public V getItemByIndex(int i) {
        return (V) super.get(keysList.get(i));
    }

    public int getIndexByKey(K key) {
        return keysList.indexOf(key);
    }
}

그런 다음이 사용자 지정 LinkedHasMap을 다음과 같이 사용할 수 있습니다.

IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();

가치를 추가하려면

indexedLinkedHashMap.add("key1",UserModel);

인덱스로 값을 얻으려면

indexedLinkedHashMap.getItemByIndex(position);

1

HashMaps는 위치 별 액세스를 허용하지 않으며 해시 코드에 대해서만 알고 있으며 키의 해시 코드를 계산할 수 있으면 값을 검색 할 수 있습니다. TreeMap에는 정렬 개념이 있습니다. Linkedhas 맵은 맵에 들어간 순서를 유지합니다.


0

다음과 같은 것을 구현해 볼 수 있습니다.

Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("juan", 2);
map.put("pedro", 3);
map.put("pablo", 5);
map.put("iphoncio",9)

List<String> indexes = new ArrayList<String>(map.keySet()); // <== Parse

System.out.println(indexes.indexOf("juan"));     // ==> 0
System.out.println(indexes.indexOf("iphoncio"));      // ==> 3

이것이 당신에게 효과가 있기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.