위치로 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.