Bagaimana cara mengambil elemen dari HashMap berdasarkan posisinya, apakah mungkin sama sekali?
Bagaimana cara mengambil elemen dari HashMap berdasarkan posisinya, apakah mungkin sama sekali?
Jawaban:
HashMaps tidak mempertahankan pemesanan:
Kelas ini tidak menjamin urutan peta; Secara khusus, ini tidak menjamin bahwa pesanan akan tetap konstan dari waktu ke waktu.
Lihat LinkedHashMap , yang menjamin urutan iterasi yang dapat diprediksi.
Gunakan LinkedHashMap dan ketika Anda perlu mengambil berdasarkan posisi, ubah nilainya menjadi 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);
Jika Anda ingin mempertahankan urutan penambahan elemen ke peta, gunakan LinkedHashMap
sebagai lawan hanya HashMap
.
Berikut adalah pendekatan yang memungkinkan Anda mendapatkan nilai dengan indeksnya di peta:
public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}
Jika Anda, karena alasan tertentu, harus tetap menggunakan hashMap, Anda dapat mengonversi keySet ke array dan mengindeks kunci dalam array untuk mendapatkan nilai di peta seperti ini:
Object[] keys = map.keySet().toArray();
Anda kemudian dapat mengakses peta seperti:
map.get(keys[i]);
String myKey = keys[i].toString();
Penggunaan LinkedHashMap
:
Tabel hash dan implementasi daftar tertaut dari antarmuka Peta, dengan urutan iterasi yang dapat diprediksi. Implementasi ini berbeda dari HashMap karena mempertahankan daftar tertaut ganda yang berjalan melalui semua entri.
Gunakan LinkedHashMap dan gunakan fungsi ini.
private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
Definisikan seperti ini dan.
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;
}
Fungsi ini dapat mengembalikan entri yang dipilih.
Saya berasumsi dengan 'posisi' Anda mengacu pada urutan di mana Anda telah memasukkan elemen ke dalam HashMap. Dalam hal ini Anda ingin menggunakan LinkedHashMap. Namun LinkedHashMap tidak menawarkan metode pengakses; Anda perlu menulis satu suka
public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}
Pendekatan kerja lainnya adalah mengubah nilai peta menjadi array dan kemudian mengambil elemen pada indeks. Uji coba 100 000 elemen dengan pencarian indeks di LinkedHashMap dari 100 000 objek menggunakan pendekatan berikut menghasilkan hasil sebagai berikut:
//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
Secara keseluruhan, mengambil elemen dengan indeks dari LinkedHashMap tampaknya merupakan operasi yang cukup berat.
HashMap - dan struktur data yang mendasarinya - tabel hash, tidak memiliki gagasan tentang posisi. Tidak seperti LinkedList atau Vector, kunci masukan diubah menjadi 'keranjang' tempat nilai disimpan. Bucket ini tidak dipesan dengan cara yang masuk akal di luar antarmuka HashMap dan oleh karena itu, item yang Anda masukkan ke HashMap tidak berurutan seperti yang Anda harapkan dengan struktur data lainnya.
HashMap tidak memiliki konsep posisi sehingga tidak ada cara untuk mendapatkan objek berdasarkan posisi. Objek di Maps diatur dan didapatkan dengan kunci.
Secara default, java LinkedHasMap tidak mendukung untuk mendapatkan nilai berdasarkan posisi. Jadi saya sarankan pergi dengan disesuaikanIndexedLinkedHashMap
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);
}
}
Kemudian Anda dapat menggunakan LinkedHasMap yang disesuaikan ini sebagai
IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();
UNTUK menambahkan Nilai
indexedLinkedHashMap.add("key1",UserModel);
Untuk mendapatkan nilai berdasarkan indeks
indexedLinkedHashMap.getItemByIndex(position);
HashMaps tidak mengizinkan akses berdasarkan posisi, ia hanya mengetahui tentang kode hash dan dan dapat mengambil nilainya jika dapat menghitung kode hash dari kunci tersebut. TreeMaps memiliki gagasan tentang pengurutan. Peta Linkedhas mempertahankan urutan mereka memasuki peta.
Anda dapat mencoba menerapkan sesuatu seperti itu, lihat:
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
Saya harap ini berhasil untuk Anda.