5
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.

Neel
  • 429
  • 7
  • 17

1 Answers1

16

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.
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 1
    Can you please explain what actually do you mean by "'10' is lexicographically smaller than '2'". – Neel Jun 08 '11 at 15:10
  • Read the linked JavaDocs while I type something up. – Matt Ball Jun 08 '11 at 15:11
  • 2
    "10" is less than "2" just as "BA" is less than "C". In your case the "1" in "10" is less than "2". – Steve Kuo Jun 08 '11 at 15:15
  • Hi matt this is not the answer I was expecting. I knew that actually the underlying fact is String's compareTo method compares strings lexicographically as I couldn't understand the meaning of lexicographically I uploaded this question. – Neel Jun 08 '11 at 15:22
  • See my edit. It's a bit long-winded, but hopefully it's clear. – Matt Ball Jun 08 '11 at 15:32