Самый удобный способ получить последний ключ или значение в LinkedHashMap? - PullRequest
7 голосов
/ 03 сентября 2011

LinkedHashMap в описании сказано, что «он поддерживает двусвязный список, проходящий через все его записи», поэтому мне интересно, как получить последнюю введенную запись или ключ? Могу ли я с уверенностью понизить значение .values() до LinkedList, чтобы получить этот двусвязный список и использовать .getLast() этого? Или это экземпляр какой-то другой коллекции Java?

Я хочу придерживаться java.util, если это возможно.

Ответы [ 4 ]

1 голос
/ 03 сентября 2011

Да, вы можете получить последний элемент. Но вам придется посмотреть на предложения других, чтобы получить последний элемент Collection<V>, возвращаемый values().

Я проверил в исходном коде, что возвращаемые значения действительно в ожидаемом порядке: AbstactCollection<V>, возвращаемое LinkedListMap.values(), поддерживается Iterator<V> над значениями, которое непосредственно связано с Iterator<K> над ключами. И, очевидно, Iterator<K> над ключами реализован с помощью упорядоченного двусвязного списка.

1 голос
/ 03 сентября 2011

Обновление: Мой предыдущий ответ был неверным.Вы не можете сделать это без изменения поведения по умолчанию!Смотрите ниже, почему.


.. как получить последнюю введенную запись или введенный ключ?

Из описания API LinkedHashMap вы можете прочитать:

Структурная модификация - это любая операция, которая добавляет или удаляет одно или несколько отображений или, в случае упорядоченных по доступу связанных хеш-карт, влияет на порядок итераций.В упорядоченных по вставке связанных хэш-картах простое изменение значения, связанного с ключом, который уже содержится в карте, не является структурной модификацией .В упорядоченных по доступу связанных хеш-картах простой запрос карты с помощью get является структурной модификацией .

Так что же все это значит?

  • access-order - каждый раз, когда вы делаете put или get, порядок элементов меняется
  • заказ на вставку - при вставке элементов (впервые) они добавляются последними

Например:

map.put(1, 1); 
map.put(2, 2); 
map.put(1, 10);
System.out.println(map);

...напечатает {1=10, 2=2} с с указанием вставки и {2=2, 1=10} с * с указанием доступа '.Проблема заключается в использовании access-ordered, если, конечно, если вы выполняете операции get, порядок также меняется.


Как исправить

Итак ... как исправить.Ну, LinkedHashMap нельзя использовать напрямую.Таким образом, вы можете обернуть его (не обращая внимания на банальное имя) и переопределить методы put и putAll, чтобы они сначала удаляли ключ с карты, а затем возвращали его обратно!

class BestLinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    @Override
    public V put(K key, V value) {
        V last = super.remove(key);
        super.put(key, value);
        return last;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        for (K key : m.keySet())
            super.remove(key);

        super.putAll(m);
    }
}

Затем, чтобы получить последний элемент, выполните:

  • , оберните вывод из реализации LinkedList:

    V v = new LinkedList<V>(map.values()).getLast();
    
  • toArray() way:

    Collection<V> values = map.values();
    V v = values.toArray(new V[0])[values.size() - 1];
    
  • итерация до последнего элемента с использованием итератора:

    Iterator<V> it = values.iterator();
    V last = null;
    while (it.hasNext())
        last = it.next();
    
0 голосов
/ 21 июня 2015

Я "расширил" Jedk LinkedHashMap, чтобы позволить это, вы можете взглянуть на: LinkedHashMapEx.java

0 голосов
/ 03 сентября 2011

Нет, извините, вы не можете.

«Поддерживаемый двусвязный список» не является типом java.util.LinkedList или другой коллекцией.Он реализован вручную в классах LinkedHashMap и LinkedHashMap.Entry.

Вы можете построить только LinkedList из values() и затем использовать letLast():

Foo last = new LinkedList<Foo>(myLinkedHashMap.values()).getLast();
...