HashMap'ten pozisyonuna göre eleman almak mümkün müdür?


101

HashMap'ten bir öğe konumuna göre nasıl alınır, bu mümkün mü?


11
"Pozisyon" ile ne demek istiyorsun? HashMap'ler sıralı değildir, bu yüzden bir Vector gibi bir şeyle elde edeceğiniz olağan "konum" kavramına sahip değildirler.
Mat

1
Ekleme siparişinden mi yoksa başka bir siparişten mi bahsediyorsunuz?
Mark Elliot

Yanıtlar:


94

HashMap'ler sıralamayı korumaz:

Bu sınıf, haritanın düzeniyle ilgili hiçbir garanti vermez; özellikle, sıranın zaman içinde sabit kalacağını garanti etmez.

Öngörülebilir bir yineleme sırasını garanti eden LinkedHashMap'e bir göz atın .


17
Bu gerçekten soruya cevap vermiyor. Aşağıdaki diğer cevaplar daha kullanışlıdır.
forresthopkinsa

6
Saygıyla, bu soruyu doğrudan yanıtlayan belgelere atıfta bulunuyor
Wayne

1
Emir zaman içinde sabit olmasa bile, üyelerden birini belirli bir pozisyondan almak yine de mümkün olabilir.
Başlangıç

Ben takip etmiyorum Açıklamak?
Wayne

HashMap bağlantısı bozuk / 404.
Raf

112

Bir LinkedHashMap kullanın ve konuma göre almanız gerektiğinde değerleri bir ArrayList'e dönüştürün.

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);

3
HashMap'den anahtarların bir kopyasını oluşturmak için her zaman gereklidir?
Richard

bu, değeri her aldığımızda yeni bir ArrayList nesnesi oluşturacak ve bellek sızıntılarına yol
açacak

49

Öğeleri haritaya eklediğiniz sırayı korumak istiyorsanız, LinkedHashMapsadece yerine kullanın HashMap.

İşte haritadaki indeksine göre bir değer almanızı sağlayacak bir yaklaşım:

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

1
En basitini söylemeliyim ... Her şeyi dönüştürmek yerine, yalnızca anahtar seti kullanıyorsunuz. Süper
kirtan403

20

Herhangi bir nedenle hashMap'e bağlı kalmak zorunda kalırsanız, keySet'i bir diziye dönüştürebilir ve haritadaki değerleri şu şekilde almak için dizideki anahtarları indeksleyebilirsiniz:

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

Daha sonra haritaya şu şekilde erişebilirsiniz:

map.get(keys[i]);

Arr [i] 'nin şu şekilde değiştirilmesi gerektiğini unutmayın: keys [i]
Mohsen Abasi

Tamam, harita anahtarları olarak Dizelerim var, bunlardan birini almak için ikinci bölüm:String myKey = keys[i].toString();
Orici

12

Kullanım LinkedHashMap:

Tahmin edilebilir yineleme sırası ile Harita arayüzünün karma tablosu ve bağlantılı liste uygulaması. Bu uygulama HashMap'ten farklıdır, çünkü tüm girişleri boyunca çalışan çift bağlantılı bir liste tutar.


27
bu, sırayı koruyacaktır, ancak öğelere dizinlerine göre erişemezsiniz.
Yinelemeniz

bu bağlantı, API'nin eski bir sürümüne yöneliktir. Java 6 veya 7 API'ye bağlanmanızı öneririm.
jzd

6

LinkedHashMap'i kullanın ve bu işlevi kullanın.

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

Bunun gibi tanımla ve.

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;
    }

İşlev, seçilen girişi döndürebilir.


3

Öğeleri HashMap'e eklediğiniz sıraya 'konum' derken kastettiğinizi varsayıyorum. Bu durumda bir LinkedHashMap kullanmak istersiniz. LinkedHashMap ancak bir erişimci yöntemi sunmaz; bir tane yazman gerekecek

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

3

Başka bir çalışma yaklaşımı, eşleme değerlerini bir diziye dönüştürmek ve ardından dizindeki öğeyi almaktır. Aşağıdaki yaklaşımlar kullanılarak LinkedHashMap'te 100.000 nesnenin dizin aramalarına göre 100.000 öğenin test çalıştırması aşağıdaki sonuçlara yol açtı:

//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

Sonuçta LinkedHashMap'ten indekse göre öğe alma oldukça ağır bir işlem gibi görünüyor.


2

HashMap - ve temel alınan veri yapısı - hash tabloları, bir konum kavramına sahip değildir. LinkedList veya Vector'den farklı olarak, giriş anahtarı, değerin depolandığı bir "paket" e dönüştürülür. Bu kovalar, HashMap arayüzünün dışında mantıklı olacak şekilde sıralanmaz ve bu nedenle HashMap'e koyduğunuz öğeler diğer veri yapılarıyla beklediğiniz anlamda sıralı değildir.


2

HashMap'in konum kavramı yoktur, bu nedenle bir nesneyi konuma göre almanın bir yolu yoktur. Haritalar'daki nesneler ayarlanır ve anahtarlarla alınır.


2

anahtarı almak için aşağıdaki kodu kullanabilirsiniz: String [] keys = (String[]) item.keySet().toArray(new String[0]);

ve aşağıdaki gibi bu öğenin anahtarıyla HashMap'e eklenen nesne veya listeyi alın: item.get(keys[position]);


2

Varsayılan olarak, java LinkedHasMap konuma göre değer almayı desteklemez. Bu yüzden özelleştirilmiş ile gitmenizi öneririmIndexedLinkedHashMap

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);
    }
}

Daha sonra bu özelleştirilmiş LinkedHasMap'i şu şekilde kullanabilirsiniz:

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

Değerler eklemek için

indexedLinkedHashMap.add("key1",UserModel);

Endekse göre getValue

indexedLinkedHashMap.getItemByIndex(position);

1

HashMap'ler konuma göre erişime izin vermez, yalnızca hash kodunu bilir ve anahtarın hash kodunu hesaplayabilirse değeri alabilir. TreeMap'lerin bir sıralama anlayışı vardır. Bağlantılı haritalar, haritaya girdikleri sırayı korur.


0

Bunun gibi bir şey uygulamayı deneyebilirsiniz, bakın:

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

Umarım bu sizin için işe yarar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.