HashMap'ten bir öğe konumuna göre nasıl alınır, bu mümkün mü?
HashMap'ten bir öğe konumuna göre nasıl alınır, bu mümkün mü?
Yanıtlar:
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 .
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);
Öğeleri haritaya eklediğiniz sırayı korumak istiyorsanız, LinkedHashMap
sadece 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 ] );
}
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]);
String myKey = keys[i].toString();
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.
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.
Öğ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;
}
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.
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.
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.
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);
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.
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.