15

Possible Duplicate:
Iterating through a LinkedHashMap in reverse order

How to traverse Linked Hash Map in a reverse order? Is there any predefined method in map to do that?

I'm creating it as follows:

LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer,String>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
Community
  • 1
  • 1
Jagadeesh
  • 2,730
  • 6
  • 30
  • 45
  • 3
    See http://stackoverflow.com/questions/7170871/iterating-through-a-linkedhashmap-in-reverse-order –  Jan 17 '12 at 10:45

3 Answers3

19

Try this, it will print the keys in reverse insertion order:

ListIterator<Integer> iter =
    new ArrayList<>(map.keySet()).listIterator(map.size());

while (iter.hasPrevious()) {
    Integer key = iter.previous();
    System.out.println(key);
}

You can also iterate by the reverse insertion order of entries:

ListIterator<Map.Entry<Integer, String>> iter =
    new ArrayList<>(map.entrySet()).listIterator(map.size());

while (iter.hasPrevious()) {
    Map.Entry<Integer, String> entry = iter.previous();
    System.out.println(entry.getKey() + ":" + entry.getValue());
}
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • I don't think this will work as the list iterator starts are the beginning of the list thus iter.hasPrevious() will be false on the very first call – Gareth Davis Jan 17 '12 at 10:57
  • 3
    @GarethDavis you're wrong, the above list iterator starts at the _end_ of the list - that's what `listIterator(map.size())` does. – Óscar López Jan 17 '12 at 11:06
  • listIterator is overloaded,one with no argument and one with position argument.listIterator() is same as listIterator(0) – Kumar Abhinav Jan 29 '14 at 07:09
  • 1
    You might modify the first line to: ListIterator iter = new ArrayList(map.keySet()).listIterator(map.size()); for type safety reasons. Thank you for this answer, it fixed my problem. – kshepherd Nov 20 '14 at 13:44
12
List<Entry<Integer,String>> list = new ArrayList<>(map.entrySet());

for( int i = list.size() -1; i >= 0 ; i --){
    Entry<Integer,String> entry = list.get(i);
}

Not really pretty and at the cost of a copy of the entry set, which if your map has a significant number of entries might be a problem.

The excellant Guava library have a [List.reverse(List<>)][2] that would allow you to use the Java 5 for each style loop rather than the indexed loop:

//using guava
for( Entry entry : Lists.reverse(list) ){
    // much nicer
}
Gareth Davis
  • 27,701
  • 12
  • 73
  • 106
4

Guava RULES:

List<Object> reverseList = Lists.reverse(
        Lists.newArrayList(map.keySet()));

Lists.reverse

John B
  • 32,493
  • 6
  • 77
  • 98