Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

elements of HashMap are in the wrong order [duplicate]

Tags:

java

hashmap

I need to read two columns (both String) from a file and keep the values of the first column in a HashMap where the Integer is the counter.

For example if the file I am reading is

Apple Fruit
PC    Device
Pen   Tool
...

and the code is

    String line="";
    int counter=1;
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt"),"Unicode"));
    while ((line = reader.readLine()) != null)
    {
        String[] words;
        words= st.split(" ");
            tokens.put(counter, words[0]);
        counter+=1;
    }

The problem is when I print The HashMap values, I found the values are in different order of that in the origianl file

        for (Map.Entry<Integer, String> token:tokens.entrySet())
    {
        System.out.println(token.getKey() + token.getValue());
    }

I got the following

1   Apple
3   Pen
4   whatever
2   ..etc

I do not know what is the problem?! can you please help me with that

like image 988
Wahedsaw Avatar asked May 31 '13 18:05

Wahedsaw


People also ask

Are duplicate values allowed in HashMap?

HashMap stores key, value pairs and it does not allow duplicate keys. If the key is duplicate then the old key is replaced with the new value.

Is duplicate allowed in map?

The map implementations provided by the Java JDK don't allow duplicate keys. If we try to insert an entry with a key that exists, the map will simply overwrite the previous entry.

Does HashMap guarantee default ordering?

toMap returns a new HashMap, but as we know, HashMap doesn't guarantee iteration order, while LinkedHashMap does.

How do I reverse the order of a HashMap?

Method 1: ( Using reverse() method) This method is used to reverse the elements or mappings order in the LinkedHashMap. Parameters: myList is the List provided to the Collections. reverse(myList) method. Returns: It does not return anything but modifies the list internally.


4 Answers

As the documentation clearly states, HashMaps are unordered.
The enumeration order is determined by the hascodes of the keys.

If you want to preserve insertion order when enumerating the map, use LinkedHashMap.
If you want enumeration order to follow the natural ordering of the keys, use TreeMap.

like image 108
SLaks Avatar answered Oct 23 '22 02:10

SLaks


HashMap is not ordered. You don't have any control over what order the items appear in. If you want an ordered map, you can use, for example, TreeMap.

EDIT: thanks to those that brought this up: TreeMap will keep items in the natural sorting order (i.e. in your case in alphabetical order). LinkedHashMap will preserve the order of insertion.

like image 34
Aleks G Avatar answered Oct 23 '22 00:10

Aleks G


Use LinkedHashMap , if you want insertion order back. By default HashMap's iterator doesn't guarantee insertion order.

like image 3
Peeyush Avatar answered Oct 23 '22 00:10

Peeyush


HashMap is not an ordered Collection. (It is not even a Collection) It is more like a dictionary.

If you want to perserve the order of the items you can either use a TreeMap or a LinkedHashMap.

The difference between these is that TreeMap keeps them ordered by their natural sort order while LinkedHashMap keeps the insertion order.

In most cases where you would like to have something like with using a List you can use the LinkedHashMap.

TreeMap uses a red-black tree for its internal implementation while LinkedHashMap uses doubly linked list.

My suggestion is that you should refer to the official documentation. There you will find thorough explanations.

Additionally the idiomatic way to iterate over Maps is this:

for(Integer key : map.keySet()) {
    String myString = map.get(key);
    // ...
}
like image 2
Adam Arold Avatar answered Oct 23 '22 00:10

Adam Arold