0

This question is just out of curiosity, but I've noticed that iterating over a HashMap using keyset seems to always go in sorted order. Obviously insertion order is never preserved with HashMaps, but sorted key order seems a bit strange to me. Using this example:

import java.util.HashMap;

public class test {
    public static void main(String[] args) {
        HashMap<Integer, String> someMap = new HashMap<Integer, String>();

        someMap.put(0, "nothing");
        someMap.put(7, "nothing");
        someMap.put(3, "nothing");
        someMap.put(4, "nothing");
        someMap.put(10, "nothing");
        someMap.put(11, "nothing");
        someMap.put(2, "nothing");
        someMap.put(1, "nothing");
        someMap.put(5, "nothing");

        for (Integer someInt : someMap.keySet()) {
            System.out.println(someInt);
        }
    }
}

output:

0
1
2
3
4
5
7
10
11

Is this dependable and consistent? If the HashMap implementation is an array, this would make sense if keyset just iterates over all available array indexes starting from 0, but I'm probably wrong and it's more complex than that.

VagrantC
  • 687
  • 2
  • 13
  • 31

3 Answers3

2

No particular order is guaranteed for the HashMaps and HashSets, period. You may derange your order by removing and adding some elements.

Checkout this:

import java.util.HashMap;

public class test {
    public static void main(String[] args) {
        HashMap<Integer, String> someMap = new HashMap<Integer, String>();

        someMap.put(0, "nothing");
        someMap.put(7, "nothing");
        someMap.put(3, "nothing");
        someMap.put(4, "nothing");
        someMap.put(10, "nothing");
        someMap.put(11, "nothing");
        someMap.put(2, "nothing");
        someMap.put(10004, "nothing");
        someMap.put(1, "nothing");
        someMap.put(5, "nothing");

        for (Integer someInt : someMap.keySet()) {
            System.out.println(someInt);
        }
    }
}

In hashsets of most sorts the hashing function rules out where particular value goes.

Yoda
  • 17,363
  • 67
  • 204
  • 344
  • Ok, that's what I thought. This behavior was just consistent among all my tests so just piqued my interest. – VagrantC Feb 28 '18 at 21:06
  • @user3625087 Cool, you may have a look at the Java's source code to understand how the `hashCode()` method is used there, but I wouldn't say it's necessary thing to do ; ) – Yoda Feb 28 '18 at 21:16
  • Whoever downvoted this answer, please let me know how I could improve it or why do you think it's of a low quality. Thank you. – Yoda Mar 01 '18 at 09:15
1

From the javadoc:

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 are seeing may be a coincidence regarding JVM implementation and how hashcodes are being managed, or maybe (but less likely):

Note that using many keys with the same hashCode() is a sure way to slow down performance of any hash table. To ameliorate impact, when keys are Comparable, this class may use comparison order among keys to help break ties.

In any case, this is not dependable or constant.

Brandon McKenzie
  • 1,655
  • 11
  • 26
1

It might be so; but since its not documented in java docs, you shouldn't code depending on such behaviour. Since new java versions can change the HashMap implementation and this may give non-ascending order keys; and so whatever code you have done depending on such behaviour will break

Alanpatchi
  • 1,177
  • 10
  • 20