6

I have such code:

HashMap<Long, TempPosition> positions = getTempPositions();
    for (SortedMap.Entry<Long, TempPosition> p: positions.entrySet()) {...}

The problem is the 'positions' is not sorted or non valid sorted. What the easiest way to iterate through the hashmap and save its current order?

Thank you

nKognito
  • 6,297
  • 17
  • 77
  • 138

7 Answers7

10

A HashMap by definition doesn't have an order. If you need to preserve or create some kind of order you need to use TreeMap instead of HashMap.

Till Helge
  • 9,253
  • 2
  • 40
  • 56
4

A HashMap doesn't have any order. If you want insertion order, use a LinkedHashMap. If you want keys sorted using their natural ordering or a custom comparator, use a TreeMap.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
4

HashMap doesn't have an order. You can't even guarentee that two HashMaps with the same keys will have the same order.

If you want an order using TreeMap or LinkedHashMap and the iterator will be in the order the collection provides.


Note: In some situations the keys will be sorted, so the keys are not even guarenteed to be random.

HashMap<Integer, String> map = new HashMap<>();
for(int i=0;i<10;i++)
    map.put(i, ""+i);
System.out.println(map.keySet());

prints

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Here you have a sample code using streams and classic foreach loop:

HashMap<String,String> map = new HashMap<>();
map.put("c", "C");
map.put("a", "A");
map.put("b", "B");

for (Map.Entry<String,String> e : (Iterable<Map.Entry<String,String>>) map.entrySet().stream().sorted(Map.Entry.comparingByKey())::iterator) {
    System.out.println("key:" + e.getKey() + ", val: " + e.getValue());
}
adaslaw
  • 170
  • 11
1

You can use an implementation of java.util.SortedMap, like java.util.TreeMap instead of HashMap.

Alberto
  • 1,569
  • 1
  • 22
  • 41
1
 SortedSet<String> sortedset= new TreeSet<String>(positions.keySet());

    Iterator<String> it = sortedset.iterator();

    while (it.hasNext()) {
      System.out.println (it.next());
    }
Sashi Kant
  • 13,277
  • 9
  • 44
  • 71
1

Since the key can be sorted, this approach is the most simple:

HashMap<Long, TempPosition> positions = getTempPositions();
for (Map.Entry<Long, TempPosition> p: 
    new TreeMap<Long, TempPosition>( positions ).entrySet()) {...}

The trick is to wrap the map in a TreeMap. Note that this doesn't work (well) if the map is huge.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • If it's just to iterate, I would bet that storing all the entries into a list and sorting the list would be faster. – JB Nizet Oct 26 '11 at 07:34
  • True but if it was just to iterate, why is OP using a `Map.Entry` as loop variable? – Aaron Digulla Oct 26 '11 at 12:45
  • 1
    To iterate over the entries (key + value). Your code does exactly the same thing (iterate over entries). And what I suggest is using a list of Map.Entry and sort it. – JB Nizet Oct 26 '11 at 13:07
  • Hm. Didn't think of that. This would prevent to build the complex binary `TreeMap`. The downside is that you'd need to write a `Comparator` that works on `getKey()`. – Aaron Digulla Oct 26 '11 at 15:12