简体   繁体   中英

java comparing integers as strings with a comparator - odd results

I'm attemping to compare some players with a comparator by the amount of runs they have obtained.

System.out.println("Comparing: " + p2.getRuns() + " and " + p1.getRuns());
int newRESULT = intConvert(p2.getRuns()).compareTo(intConvert(p1.getRuns()));
System.out.println("Returns: " + newRESULT);
return newRESULT;

However this returns:

Comparing: 25 and 0, Returns: 2

Comparing: 0 and 100, Returns: -1

Comparing: 25 and 100, Returns: 1

...and hence orders the players in the wrong order.

Should the first comparison not return 1, the second -1 and the last -1 as well?

intConvert:

     private static String intConvert(int x)
     {
      return "" + x;
     }

I assume intConvert(...) converts an int to a String , and thus you get lexical comparisons which meahs "25" is greater than "100" because the first character is greater (2 > 1).

If you want to get correct comparisons stick to comparing int s or if you need to use a String create strings of equal length and fill in missings zeros at the front (eg 25 -> "025") .

To compare Numbers that are represented as String in a sensible way, you need to consistently format them all the same way.

String s use lexical comparisons. This means "5" will be > "20" because 5 is > than 2 . To get the logically expected output you need to format the numbers with some kind of formatter to make them lexically comparable.

"05" is < "20"

The simplest thing would be to use String.format() and a pattern to format all the numbers to Strings so they will compare consistently lexically.

String.format("%04d", yourInteger);

This will produce all int s that are passed in as left padded with 0 for 4 positions.

String.format("%04d", 5);

will produce 0005

Make the "%0Xd" where X is the number of digits you want it formatted to.

You don't have to convert the numbers to strings just to sort, you can do something like:

class ComparePlayersByRuns implements Comparator<Player> {
    public int compareTo(Player p1, Player p2) {
        return p1.getRuns().compareTo(p2.getRuns());
    }
}

or in Java 8 and later all you need to create your comparator is:

Comparators.comparing(Player::getRuns);

And no, the compare isn't required to return 1, 0, or -1, the documentation says:

Returns:

a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM