Iterating through a LinkedHashMap in reverse order

大憨熊 提交于 2019-12-17 06:13:07

问题


I have a LinkedHashMap:

LinkedHashMap<String, RecordItemElement>

that I need to iterate through from a given key's position, backwards. So if I was given the 10th item's key, I'd need iterate backwards through the hashmap 9, 8, 7 etc.


回答1:


You don't have to iterate through it. But it would be handy to pull the keys off and store it in a list. Thats the only way you can do indexOf() type operations.

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)));



回答2:


The question requires a LinkedHashMap in reverse order, some answers suggesting using a TreeSet but this will reorder the map based upon the key.

This solution allows the iteration over the original LinkedHashMap not the new ArrayList as has also been proposed:

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



回答3:


The HashMap:

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

For reverse iterating over values:

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

For reverse iterating over keys:

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

For reverse iterating over both:

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();



回答4:


new LinkedList(linkedHashMap.keySet()).descendingIterator();



回答5:


Using "user22745008" solution and labdas with some generics you can have a very neat solution as a method:

  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:


This is an old question, but I think it's lacking an answer that takes a newer approach. The following uses Java 9 features:

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

The code above streams the map's entryset, keeping entries until a key equal to the given key is found. Then, the entries are collected to an ArrayDeque.

One detail is missing, though. Depending on whether you need the entry that matches the given key to also be included in the result or not, you might need to manually add it to the deque. If you don't want it added, then you're done. Otherwise, simply do:

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

Now, to iterate the Deque in reverse order, simply use its descendingIterator():

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

It's worth mentioning that this approach only works if the stream is sequential. Anyways, we wouldn't have gained anything using a parallel stream here.



来源:https://stackoverflow.com/questions/7170871/iterating-through-a-linkedhashmap-in-reverse-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!