Итерация через LinkedHashMap в обратном порядке

У меня есть LinkedHashMap:

LinkedHashMap<String, RecordItemElement>

что мне нужно пройти через заданную позицию ключа назад. Поэтому, если мне был присвоен ключ 10-го пункта, мне понадобится повторить итерацию через хэш-карту 9, 8, 7 и т.д.

Ответ 1

Вам не нужно проходить через нее. Но было бы удобно вытащить ключи и сохранить их в списке. Это единственный способ, которым вы можете выполнять операции типа indexOf().

List<String> keyList = new ArrayList<String>(map.keySet());
// Given 10th element key
String key = "aKey";
int idx = keyList.indexOf(key);
for ( int i = idx ; i >= 0 ; i-- ) 
 System.out.println(map.get(keyList.get(i)));

Ответ 2

HashMap:

HashMap<Integer, String> map = new HashMap<Integer, String>();

Для повторного итерации над значениями:

ListIterator<Sprite> iterator = new ArrayList<String>(map.values()).listIterator(map.size());
while (iterator.hasPrevious()) String value = iterator.previous();

Для обратного итерации по клавишам:

ListIterator<Integer> iterator = new ArrayList(map.keySet()).listIterator(map.size());
while (iterator.hasPrevious()) Integer key = iterator.previous();

Для обратного итерации по обоим:

ListIterator<Map.Entry<Integer, String>> iterator = new ArrayList<Map.Entry<Integer, String>>(map.entrySet()).listIterator(map.size());
while (iterator.hasPrevious()) Map.Entry<Integer, String> entry = iterator.previous();

Ответ 3

Вопрос требует LinkedHashMap в обратном порядке, некоторые ответы предполагают использование TreeSet, но это изменит порядок карты на основе ключа.

Это решение позволяет итерации по сравнению с исходным LinkedHashMap не новым ArrayList, как было предложено:

List<String> reverseOrderedKeys = new ArrayList<String>(linkedHashMap.keySet());
Collections.reverse(reverseOrderedKeys);
for (String key : reverseOrderedKeys) {
    RecordItemElement line = linkedHashMap.get(key);
}

Ответ 4

Я бы сказал, для этого используйте TreeMap. Тогда вам не нужно копировать всю коллекцию, если вы хотите получить к ней доступ в любом порядке. Обратите внимание, что ключ должен заботиться о заказе.

TreeMap map = new TreeMap();
map.put(1, "c");
map.put(2, "b");   
map.put(3, "a");    
NavigableSet set = m.descendingKeySet();

Или посмотрите на org.apache.commons.collections. *

https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/OrderedMap.html

Ответ 5

Используя "user22745008" решение и labdas с некоторыми дженериками, вы можете иметь очень аккуратное решение в качестве метода:

  public static <T, Q> LinkedHashMap<T, Q> reverseMap(LinkedHashMap<T, Q> toReverse)
  {
      LinkedHashMap<T, Q> reversedMap = new LinkedHashMap<>();
      List<T> reverseOrderedKeys = new ArrayList<>(toReverse.keySet());
      Collections.reverse(reverseOrderedKeys);
      reverseOrderedKeys.forEach((key)->reversedMap.put(key,toReverse.get(key)));
      return reversedMap;
    }

Ответ 6

Это старый вопрос, но я думаю, что ему не хватает ответа, который требует более нового подхода. Следующее использует функции Java 9:

Deque<Map.Entry<String, RecordItemElement>> top = map.entrySet().stream()
        .takeWhile(e -> !givenKey.equals(e.getKey()))
        .collect(Collectors.toCollection(ArrayDeque::new));

Приведенный выше код выполняет потоковую передачу набора записей карты, сохраняя записи до тех пор, пока не будет найден ключ, равный данному ключу. Затем записи собираются в ArrayDeque.

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

top.add(Map.entry(givenKey, map.get(givenKey)));

Теперь, чтобы перебрать Deque в обратном порядке, просто используйте ее descendingIterator():

Iterator<Map.Entry<String, RecordItemElement>> descIt = top.descendingIterator();

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

Ответ 7

В случае, если вы можете принять обратный порядок самой карты, есть конструктор, который позволяет вам сделать это.