Як отримати елемент з HashMap за його положенням, чи можливо це взагалі?
Як отримати елемент з HashMap за його положенням, чи можливо це взагалі?
Відповіді:
HashMaps не зберігають замовлення:
Цей клас не дає жодних гарантій щодо порядку карти; зокрема, це не гарантує, що замовлення з часом залишатиметься незмінним.
Погляньте на LinkedHashMap , який гарантує передбачуваний порядок ітерації.
Використовуйте 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);
Якщо ви хочете зберегти порядок, у якому ви додавали елементи на карту, використовуйте LinkedHashMap
на відміну від просто HashMap
.
Ось підхід, який дозволить отримати значення за його індексом на карті:
public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}
Якщо вам чомусь доведеться дотримуватися hashMap, ви можете перетворити keySet в масив і проіндексувати ключі в масиві, щоб отримати значення на карті так:
Object[] keys = map.keySet().toArray();
Потім ви можете отримати доступ до карти, як:
map.get(keys[i]);
String myKey = keys[i].toString();
Використання LinkedHashMap
:
Таблиця хеш-версій та реалізація пов'язаного списку інтерфейсу Map, з передбачуваним порядком ітерації. Ця реалізація відрізняється від HashMap тим, що вона підтримує подвійно пов'язаний список, що проходить через усі його записи.
Використовуйте 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;
}
Функція може повернути вибраний запис.
Я припускаю, що "позицією" ви посилаєтесь на порядок, яким ви вставили елементи в HashMap. У цьому випадку ви хочете використовувати LinkedHashMap. Однак LinkedHashMap не пропонує метод доступу; вам потрібно буде написати один лайк
public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}
Іншим робочим підходом є перетворення значень карти в масив, а потім отримання елемента в індексі. Тестовий запуск 100 000 елемента шляхом пошуку в індексах в LinkedHashMap 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 здається досить важкою операцією.
HashMap - і основна структура даних - хеш-таблиці, не мають поняття позиції. На відміну від LinkedList або Vector, ключ введення перетворюється на "відро", де значення зберігається. Ці сегменти не впорядковані таким чином, що має сенс поза інтерфейсом HashMap, і як такі елементи, які ви вводите в HashMap, не в порядку в тому сенсі, який ви очікували б від інших структур даних
HashMap не має поняття позиції, тому немає можливості отримати об'єкт за позицією. Об'єкти на Картах встановлюються та отримуються за допомогою клавіш.
За замовчуванням 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);
HashMaps не дозволяє доступ за позицією, він знає лише хеш-код, і він може отримати значення, якщо він може обчислити хеш-код ключа. У TreeMaps є поняття впорядкування. На картах Linkedhas зберігається порядок їх внесення до карти.
Ви можете спробувати реалізувати щось подібне, подивіться на:
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
Сподіваюся, це працює для вас.