23

I am trying this for some hour but not finding any best approach to achieve iteration of hashmap in reverse order, this is the hashmap I have.

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

             for(Integer key : map.keySet()) {
                List<String> value = map.get(key);
                List<Map<String,?>> security = new LinkedList<Map<String,?>>();  
                for(int ixy = 0; ixy < value.size()-1; ixy++){
                    security.add(createItem(value.get(ixy), value.get(ixy+1))); 
                }
                adapter.addSection(Integer.toString(key), new SimpleAdapter(getApplicationContext(), security, R.layout.list_complex, new String[] { ITEM_TITLE, ITEM_CAPTION }, new int[] { R.id.list_complex_title, R.id.list_complex_caption }));  
            }

I have seen example of TreeMap as well,

             Map<Integer, List<String>> sortedMap = new TreeMap<Integer, List<String>>(map);

But treemap also gives in ascending order, what I want is in descending order.

2
  • 4
    HashMaps don't have orders, so they don't have reverse orders either. Commented May 15, 2012 at 10:21
  • See also stackoverflow.com/questions/7170871/… Commented Dec 9, 2015 at 16:36

12 Answers 12

50

best approach to acheive iteration of hashmap in reverse order

HashMap does not define any particular ordering of its element. Therefore the "reverse" order isn't defined either.

For a TreeMap, you can use descendingMap().

Sign up to request clarification or add additional context in comments.

1 Comment

Or its Java 21 equivalent, reversed().
26

Hashmap does not have specific order. But you can use TreeMap.

Perhaps this simple example can help you :

Map<Integer, String> map = new TreeMap<Integer, String>();
        map.put(1, "abc1");
        map.put(2, "abc2");
        map.put(3, "abc3");

        ArrayList<Integer> keys = new ArrayList<Integer>(map.keySet());
        for(int i=keys.size()-1; i>=0;i--){
            System.out.println(map.get(keys.get(i)));
        }

3 Comments

Note that this method is rather inefficient both in terms of memory usage and time complexity.
NPE's answer seems much more appropriate, since it does not require the space/time required to create the ArrayList`
I don't like this because it depends on an integer value in the key space. I actually prefer JB Nizet's answer of reversing the default sorting order, that way, regardless of the type of value in your key space, you can just iterate over the keys.
15

A HashMap doesn't maintain eny order between keys.

A TreeMap orders its keys by their natural order, or by the order imposed by a comparator that you pass when constructing the map. So if you want to have Integer keys ordered in reverse order, construct the TreeMap this way:

Map<Integer, List<String>> sortedMap = 
    new TreeMap<Integer, List<String>>(Collections.reverseOrder());

1 Comment

Good approach as well, though I find TreeMap#descendingMap() more elegant. U_U
6
Map<Integer, List<String>> sortedMap = new TreeMap<Integer, List<String>>(Collections.reverseOrder());

Collections.reverseOrder() keeps the map sorted in descending order.

Comments

6

You can use TreeMap#descendingKeySet method.

Map<Integer, List<String>> map = new TreeMap<Integer, List<String>>();

for(Integer key : map.descendingKeySet()) {
    List<String> value = map.get(key);
    List<Map<String,?>> security = new LinkedList<Map<String,?>>();  
    for(int ixy = 0; ixy < value.size()-1; ixy++){
        security.add(createItem(value.get(ixy), value.get(ixy+1))); 
    }
    adapter.addSection(Integer.toString(key), new SimpleAdapter(getApplicationContext(), security, R.layout.list_complex, new String[] { ITEM_TITLE, ITEM_CAPTION }, new int[] { R.id.list_complex_title, R.id.list_complex_caption }));
} 

Reference:

https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html#descendingKeySet--

Comments

4

You can't iterate over a HashMap in reverse because of this:

This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

What you should use is a LinkedHashMap:

This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map. (A key k is reinserted into a map m if m.put(k, v) is invoked when m.containsKey(k) would return true immediately prior to the invocation.)

2 Comments

unfortunately even the JDK LinkedHashMap doesn't have easy access to its internal double linked list to allow you to traverse in "reverse order" so I guess you'd basically have to "roll you own" (linked list with HashMap combined) class, unfortunately. Guava might have something that helps...
unfortunately even the JDK LinkedHashMap doesn't have easy access to its internal double linked list to allow you to traverse in "reverse order" see also stackoverflow.com/a/1936472/32453
4

The hashmap is not an ordered collection. Use TreeMap instead, which has descendingKeySet for reverse iteration. See the javadocs. LinkedHashMap is also a good choice.

Comments

4
    TreeMap<Integer, String> map = new TreeMap<Integer, String>();
    map.put(1, "abc1");
    map.put(2, "abc2");
    map.put(3, "abc3");
    NavigableMap<Integer, String> nmap = map.descendingMap();
    for (NavigableMap.Entry<Integer, String> entry : nmap.entrySet()) {
        System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
    }

An implementation of NPE idea.

Comments

3

Perhaps you need a NavigableMap, like a TreeMap.

Comments

2

But treemap also gives in asecding order, what i want is in descending order.

Implement a Comparator that will compare it reverse than natural order and then just iterate normally you will have reverse iteration

Comments

2

Use insted:

new TreeMap<>(Collections.reverseOrder())

and you will get what you want.

Comments

0

I've found that the Iterators obtained from Java Hashtable via: Hashtable.values().iterator() and Hashtable.keys().asIterator() are both in reverse order by default. One oddity, The values().iterator has a first final value of "0" which I didn't add when populating it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.