0

I have a HashMap to store my data of <Integer, ArrayList<String>>. I used put(...) to add data in the map if it does not exist yet. I used containsKey() to check if the entry is Key is already in the map. If it exists, I add the String to the key by doing this:

x.get(i).add(str)

To get the data, I just did a for loop with the keySet() of the hash.

If I have this hash:

int -> array of strings
1 -> "a", "b", "c"
2 -> "aa", "bb", "cc"
3 -> "aaa", "bbb", "ccc"

My problem is, the order of the data being read is not consistent. In 1 PC, it might read the keys in this order: 2, 1, 3. In another PC, it might read it in this order: 1, 2, 3.

I would prefer that the order in which they are read are the same across all PCs. The order into which they are entered into the hashmap is also the same, but Why is the hashmap reading the Keysets in different order?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
chris yo
  • 1,187
  • 4
  • 13
  • 30

3 Answers3

3

Did you read the Javadoc of HashMap? It makes no guarantees about ordering.

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.

If you want consistent ordering, use LinkedHashMap or TreeMap. HashMap's lack of guarantees mean that, if the Java developers choose, it can iterate backwards on Tuesdays.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • To extend the answer, the `LinkedHashSet` contains a `LinkedList` and a `HashSet` in order to remember the ordering this of course comes with an increased overhead (two additional pointers per entry). By default the concept of a `HashSet` does not allow holding any order, see [Wikipedia](https://en.wikipedia.org/wiki/Hash_table) for an explanation on how it works. – Zabuzard Jul 27 '17 at 03:07
  • Er, not exactly. There's no `LinkedList` object, the entries of the map are just modified to also form a linked list. – Louis Wasserman Jul 27 '17 at 03:10
  • Yes, that is what I meant. Maybe a bit missleading with the highlighting, sorry for that. It is just that the `Entry` also have a **previous** and a **next** pointer, forming a linked list, as you said. – Zabuzard Jul 27 '17 at 03:30
0

Actually there is no way to control the input order of the elements in Hash Map, but it is possible to sort them before porcess them.

public class HashMapSample {
    public static void main(String[] args) {
        Map<Integer,List<String>> myHash = new HashMap<>();
        myHash.put(1, Arrays.asList("a","aa","aaa"));
        myHash.put(3, Arrays.asList("c","ccc","ccc"));
        myHash.put(2, Arrays.asList("b","bb","bbb"));
        System.out.println(myHash);
        myHash.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(System.out::println);

    }
}
Daniel C.
  • 5,418
  • 3
  • 23
  • 26
  • Also not a bad idea but it probably would be better to just use a set implementation that maintains order as sorting adds a huge performance overhead. – Zabuzard Jul 27 '17 at 03:34
  • I'm very agree with you. It will depends on the problem context and what kind of requirement has to solve. Regards. – Daniel C. Jul 27 '17 at 03:50
0

You need to use TreeMap instead of HashMap