Я использовал, LinkedHashMap
потому что важно порядок, в котором ключи вводятся на карте.
Но теперь я хочу получить значение ключа первым (первая введенная запись) или последним.
Должны ли быть метод , как first()
и last()
или что - то подобное?
Нужен ли мне итератор, чтобы получить первую запись ключа? Вот почему я использовал LinkedHashMap
!
Спасибо!
java
dictionary
linkedhashmap
maiky
источник
источник
Ответы:
Семантика по-
LinkedHashMap
прежнему является семантикой карты, а не семантикиLinkedList
. Да, он сохраняет порядок вставки, но это деталь реализации, а не аспект его интерфейса.Самый быстрый способ получить «первую» запись по-прежнему
entrySet().iterator().next()
. Получение «последней» записи возможно, но повлечет за собой итерации по всему набору записей, вызывая.next()
до тех пор, пока вы не достигнете последней.while (iterator.hasNext()) { lastElement = iterator.next() }
edit : Однако, если вы хотите выйти за пределы API JavaSE, у Apache Commons Collections есть собственная
LinkedMap
реализация, в которой есть такие методы, какfirstKey
иlastKey
, которые делают то, что вы ищете. Интерфейс значительно богаче.источник
mylinkedmap.entrySet().iterator().next()
сложность времени? Это O (1)?Можете ли вы попробовать сделать что-то вроде (чтобы получить последнюю запись):
источник
T last = null ; for( T item : linkedHashMap.values() ) last = item;
Или что-то вроде того. Это O (N) во времени, но O (1) в памяти.Я знаю, что я опоздал, но я хотел бы предложить несколько альтернатив, не что-то экстраординарное, но некоторые случаи, которые здесь не упоминались. В случае, если кто-то не очень заботится об эффективности, но хочет чего-то более простого (возможно, найдет значение последней записи с одной строкой кода), все это будет довольно упрощено с появлением Java 8 . Я приведу несколько полезных сценариев.
Ради полноты я сравниваю эти альтернативы с решением массивов, которые уже упоминались в этом посте другими пользователями. Я суммирую все случаи, и я думаю, что они будут полезны (когда производительность имеет значение или нет), особенно для новых разработчиков, всегда зависит от вопроса каждой проблемы
Возможные альтернативы
Использование метода Array
Я взял это из предыдущего ответа, чтобы сделать следующие сравнения. Это решение принадлежит @feresr.
Использование метода ArrayList
Аналогично первому решению с немного другой производительностью
Уменьшить метод
Этот метод уменьшит набор элементов до получения последнего элемента потока. Кроме того, он будет возвращать только детерминированные результаты
Метод SkipFunction
Этот метод получит последний элемент потока, просто пропустив все элементы перед ним
Итеративная альтернатива
Вот полный исходный код
Вот вывод с производительностью каждого метода
источник
LinkedHashMap
текущая реализация (Java 8) отслеживает его хвост. Если производительность является проблемой и / или карта имеет большой размер, вы можете получить доступ к этому полю с помощью отражения.Поскольку реализация может измениться, вероятно, неплохо иметь запасную стратегию. Вы можете захотеть что-то записать, если выдается исключение, чтобы вы знали, что реализация изменилась.
Это может выглядеть так:
источник
ClassCastException
бы наcatch
всякий случайtail
неEntry
в подкласс (или будущую реализацию).Еще один способ получить первую и последнюю запись в LinkedHashMap - это использовать метод «toArray» интерфейса Set.
Но я думаю, что итерация записей в наборе записей и получение первой и последней записи - лучший подход.
Использование методов массива приводит к предупреждению о форме «... требуется непроверенное преобразование для соответствия ...», которое не может быть исправлено [но может быть подавлено только с помощью аннотации @SuppressWarnings («unchecked»)].
Вот небольшой пример, демонстрирующий использование метода "toArray":
источник
Это немного грязно, но вы можете переопределить
removeEldestEntry
метод LinkedHashMap, который может подойти вам как частному анонимному члену:Таким образом, вы всегда сможете получить первую запись у вашего
eldest
участника. Он будет обновляться каждый раз, когда вы выполняетеput
.Также должно быть легко переопределить
put
и установитьyoungest
...Все это ломается, когда вы начинаете удалять записи, хотя; Я не нашел способ запутать это.
Это очень раздражает, что вы не можете получить доступ к голове или хвосту разумным способом ...
источник
Возможно, что-то вроде этого:
источник
Предложение:
источник
Я бы порекомендовал использовать ConcurrentSkipListMap, который имеет
firstKey()
иlastKey()
методыисточник
Для использования первого элемента
entrySet().iterator().next()
и прекращения итерации после 1 итерации. Для последнего самый простой способ - сохранить ключ в переменной всякий раз, когда вы выполняете map.put.источник
Хотя connectedHashMap не предоставляет какого-либо метода для получения первого, последнего или какого-либо конкретного объекта.
Но это довольно тривиально, чтобы получить:
Set al = orderMap.keySet ();
теперь с помощью итератора объекта al; Вы можете получить любой объект.
источник
Да, я столкнулся с той же проблемой, но, к счастью, мне нужен только первый элемент ... - Это то, что я сделал для этого.
Если вам также нужен последний элемент - я посмотрю, как изменить порядок вашей карты - сохраните его во временной переменной, получите доступ к первому элементу на обратной карте (следовательно, это будет ваш последний элемент), убейте временная переменная
Вот несколько хороших ответов о том, как изменить порядок хэш-карт:
Как перебрать hashmap в обратном порядке в Java
Если вы пользуетесь помощью по приведенной выше ссылке, пожалуйста, проголосуйте за них :) Надеюсь, это кому-нибудь поможет.
источник
правильно, вы должны вручную перечислить набор ключей до конца связанного списка, затем получить запись по ключу и вернуть эту запись.
источник
источник