Java compareTo for String and Integer arguments

Ben picture Ben · May 23, 2009 · Viewed 19.5k times · Source

I am implementing the bubble sort algorithm and I want it to be able to accept both Integer and String parameters. I cast all input as Strings and use the compareTo method to compare the integers casted as strings to the strings. I am getting an incorrect answer when using compareTo to compare the casted integers. What am I doing wrong?

Answer

Iain Samuel McLean Elder picture Iain Samuel McLean Elder · May 23, 2009

Integer.compareTo sorts numbers numerically. This is what you want.

String.compareTo sorts strings lexicographically; that is, in alphabetical order.

I remember in Windows 3.1 that the folder of photos from my digital camera was ordered like this: PHOTO1, PHOTO10, PHOTO100, PHOTO2, PHOTO20, PHOTO3, ... and so on. Windows XP sorts them more like you would expect: PHOTO1, PHOTO2, PHOTO3, ... etc. This is because it has special sorting rules for strings that represent numbers.

In lexicographical ordering, each character in one string A is compared to the corresponding character in another string B. For each corresponding character in the two strings:

  • If A's current character is lexicographically less than (comes before in the alphabet) B's character, then A comes before B.
  • If B's character is less than A's character, then B comes before A.
  • If the two characters are the same, then we don't know yet. The next one is checked.
  • If there are no more characters left in one of the strings, then the shorter one comes before the longer one.
  • If there are no more character left in both strings, then they are the same string.

The fourth point here is why you are getting incorrect answers, assuming Eddie's analysis of your problem is correct.

Consider the strings "10" and "2". Lexicographical ordering would look at the first characters of each, '1' and '2' respectively. The character '1' comes before '2' in the character set that Java uses, so it sorts "10" before "2", in the same way that "bare" is sorted before "hare" because 'b' comes before 'h'.

I suggest you cast your strings to integers before sorting. Use Integer.parseString to do this.