Java version number sort

Viewed 4553
String[] k1 = {"0.10", "0.2", "0.1", "0", "1.10", "1.2", "1.1", "1", "2.10", "2", "2.2", "2.1"};
double[] k2 = {0.10, 0.2, 0.1, 0, 1.10, 1.2, 1.1, 1, 2.10, 2, 2.2, 2.1};
Arrays.sort(k1);
Arrays.sort(k2);
System.out.println(Arrays.toString(k1));
System.out.println(Arrays.toString(k2));

output:

[0,   0.1, 0.10, 0.2,  1,   1.1, 1.10, 1.2,  2,   2.1, 2.10, 2.2]
[0.0, 0.1, 0.1,  0.2,  1.0, 1.1, 1.1,  1.2,  2.0, 2.1, 2.1,  2.2]

What I would like to have,

[0, 0.1, 0.2, 0.10, 1, 1.1, 1.2, 1.10, 2, 2.1, 2.2, 2.10]

First sort before decimals and after. Like 1, 1.1, 1.2, 1.10, 2, 2.1, etc.

How can I write a comparator for this?

4 Answers
2.1, 2.2, 2.10]

Since 2.10 is greater than 2.2 in this order it looks like a version number sort:

import java.util.Arrays;
import java.util.Comparator;

public class VersionNumberComparator implements Comparator<String> {
  @Override
  public int compare(String version1, String version2) {
    String[] v1 = version1.split("\\.");
    String[] v2 = version2.split("\\.");
    int major1 = major(v1);
    int major2 = major(v2);
    if (major1 == major2) {
      return minor(v1).compareTo(minor(v2));
    }
    return major1 > major2 ? 1 : -1;
  }

  private int major(String[] version) {
    return Integer.parseInt(version[0]);
  }

  private Integer minor(String[] version) {
    return version.length > 1 ? Integer.parseInt(version[1]) : 0;
  }

  public static void main(String[] args) {
    String[] k1 = { "0.10", "0.2", "0.1", "0", "1.10", "1.2", "1.1", "1",
        "2.10", "2", "2.2", "2.1" };
    Arrays.sort(k1, new VersionNumberComparator());
    System.out.println(Arrays.asList(k1));
  }
}

I think what you want is imposible to achive. Consider this simple example:

public static void main(String[] args) {
    double d = 0.1;
    System.out.println(d);
    d = 0.10;
    System.out.println(d);
    d = 0.100;
    System.out.println(d);
}

prints:

0.1
0.1
0.1

for java 0.1 double is the same as 0.10 and 0.100. There is no double 0.1, 0.10, 0.100 etc, there is only 0.1

You can write a Comperator that first convert the values to double and compares them, if they are equal like "0.10" & "0.1" you should compare them by length.

Related