Чи можливо отримати елемент від HashMap за його позицією?


99

Як отримати елемент з HashMap за його положенням, чи можливо це взагалі?


11
Що ви маєте на увазі під "позицією"? HashMaps не впорядковуються, тому вони не мають звичайного поняття "позиція", яке ви отримали б з чимось на зразок вектора.
Мат

1
Ви маєте на увазі його порядок вставки чи якесь інше впорядкування?
Марк Елліот

Відповіді:


94

HashMaps не зберігають замовлення:

Цей клас не дає жодних гарантій щодо порядку карти; зокрема, це не гарантує, що замовлення з часом залишатиметься незмінним.

Погляньте на LinkedHashMap , який гарантує передбачуваний порядок ітерації.


16
Це насправді не відповідає на питання. Інші відповіді нижче є більш корисними.
forresthopkinsa

6
З повагою, тут цитується документація, яка безпосередньо відповідає на питання
Уейн

1
Навіть якщо порядок з часом не є постійним, все одно можна отримати одного з членів за певною позицією.
Початківцю

Я не стежу за цим. Пояснити?
Уейн

Посилання HashMap розірвано / 404.
Раф,

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 ??
Річард

це створить новий об’єкт 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]);

Зверніть увагу, що arr [i] слід змінити на: keys [i]
Mohsen Abasi

Гаразд, у мене є рядки як ключі карти, щоб отримати один із них, другою частиною буде:String myKey = keys[i].toString();
Орічі

12

Використання LinkedHashMap:

Таблиця хеш-версій та реалізація пов'язаного списку інтерфейсу Map, з передбачуваним порядком ітерації. Ця реалізація відрізняється від HashMap тим, що вона підтримує подвійно пов'язаний список, що проходить через усі його записи.


27
це збереже замовлення, але ви все одно не можете отримати доступ до елементів за їх індексом. Вам доведеться повторити
Божо

це посилання на стару версію API. Я б запропонував посилання на API Java 6 або 7.
jzd

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

Іншим робочим підходом є перетворення значень карти в масив, а потім отримання елемента в індексі. Тестовий запуск 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 здається досить важкою операцією.


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 не дозволяє доступ за позицією, він знає лише хеш-код, і він може отримати значення, якщо він може обчислити хеш-код ключа. У TreeMaps є поняття впорядкування. На картах 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

Сподіваюся, це працює для вас.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.