Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TreeMap behaves abnormally

Tags:

java

import java.util.*;    
public class Test {
        public static void main(String[] args) {

            Map<String,String> map = new TreeMap<String,String>();
            map.put("10", "America");
            map.put("1", "Australia");
            map.put("2", "India");
            map.put("11", "China");

            System.out.println(map);

        }
    }

When running the above code snippet,in console I am getting the output as :

{1=Australia, 10=America, 11=China, 2=India}

But I am expecting output as

{1=Australia, 2=India, 10=America, 11=China}

But when changing the logic as mentioned below inside above main()

 Map<String,String> map = new TreeMap<String,String>();
        map.put("US", "America");
        map.put("AUS", "Australia");
        map.put("IN", "India");
        map.put("CH", "China");

    System.out.println(map);

I am getting the desired output

({AUS=Australia, CH=China, IN=India, US=America})

As per my understanding TreeMap's entrySet() method returns a set view of the mappings contained in the map. The set's iterator returns the mappings in ascending key order. So why this is happening in the first case?

Any suggestion is highly appreciated.

like image 315
Neel Avatar asked Jun 08 '11 14:06

Neel


1 Answers

Because "10" is lexicographically smaller than "2".


Here's a hint:

Map<Integer,String> map = new TreeMap<Integer,String>();
map.put(10, "America");
map.put(1, "Australia");
map.put(2, "India");
map.put(11, "China");

System.out.println(map);
// {1=Australia, 2=India, 10=America, 11=China}

Here's another hint: String#compareTo(String) vs Integer#compareTo(Integer).


Can you please explain what actually do you mean by "'10' is lexicographically smaller than '2'".

First, read the JavaDoc I linked, especially the first link.

Now let's review some simple string comparisons:

  • "a" obviously comes before "b"
  • likewise "b" comes before "z"

It shouldn't be much of a stretch to extend this to numerical characters:

  • "0" comes before "1"
  • "1" comes before "9"

The ordering of individual characters, such as a, b, z, 0, 1, and 9 is called their lexicographical order. In short, each character has a numerical representation which you won't find terribly surprising.

Now let's look at some slightly more complicated string comparisons:

  • "aa" comes before "bb" (this shouldn't be much of a surprise)
  • "aa" also comes before "ab"

How did we determine the second case? Character by character.

1. "a" is the same character as "a", so we need to keep going
2. "a" comes before "b", so we're done.

One more example: "ba" comes before "c", since "b" comes before "c".

Let's do the same thing for strings containing numerical characters:

  • Does "2" come before "10"? We compare character-by-character:

    1. Does "2" come before "1"? No, it comes after, so we're already done.
like image 155
Matt Ball Avatar answered Nov 20 '22 17:11

Matt Ball