Итерация по LinkedHashMap в обратном порядке - PullRequest
32 голосов
/ 24 августа 2011

У меня есть LinkedHashMap:

LinkedHashMap<String, RecordItemElement>

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

Ответы [ 5 ]

9 голосов
/ 12 августа 2014

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();
9 голосов
/ 17 февраля 2016

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

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

List<String> reverseOrderedKeys = new ArrayList<String>(linkedHashMap.keySet());
Collections.reverse(reverseOrderedKeys);
for (String key : reverseOrderedKeys) {
    RecordItemElement line = linkedHashMap.get(key);
}
7 голосов
/ 24 августа 2011

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

List<String> keyList = new ArrayList<String>(map.keySet());
// Given 10th element's key
String key = "aKey";
int idx = keyList.indexOf(key);
for ( int i = idx ; i >= 0 ; i-- ) 
 System.out.println(map.get(keyList.get(i)));
0 голосов
/ 21 января 2018

Это старый вопрос, но я думаю, что ему не хватает ответа, который использует более новый подход. Следующие функции 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();

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

0 голосов
/ 14 февраля 2017

Используя решение "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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...