-1

I'm sorting an array in Java, my inputs are {"a3", "a2", "a11", "b1", "b2", "b3", "c3", "c13", "c2"} and I want output {"a2", "a3", "a11", "b1", "b2", "b3", "c2", "c3", "c13"}

What I'm doing in below not returning proper results, any suggestions/code example appreciated

import java.util.Arrays;  

public class Main
{
    public static void main(String[] args) {
        String[] var = {"a3", "a2", "a11", "b1", "b2", "b3", "c3",  "c13", "c2"};  
        Arrays.sort(var);  
        System.out.println(Arrays.toString(var));  
    }
}

From above code I'm getting output [a11, a2, a3, b1, b2, b3, c13, c2, c3]

Hulk
  • 6,399
  • 1
  • 30
  • 52
Dev
  • 413
  • 10
  • 27
  • 6
    The result you receive is the natural order of the Strings. If you want to order a class by anything other than its natural order (defined by comparable interface) then you always need to write and provide your own custom comparator – OH GOD SPIDERS Sep 18 '20 at 13:56

1 Answers1

1

Here's a relatively simple approach. However, for something like this I would create a class to hold the alpha and numeric parts separately and write a comparator. When I print the objects I would simply have toString() return the original value.

This is basic. It does not check for malformed strings.

String[] var = {"a3", "a2", "a11", "b1", "b2", "b3", "c3",  "c13", "c2"};  

Comparator<String> comp = (a,b)->{
      // split the strings between the last char and the first digit 
      String[] v1 = a.split("(?<!\\d)(?=\\d)");
      String[] v2 = b.split("(?<!\\d)(?=\\d)");
      
      // convert each integer part to an int.
      int n1 = Integer.valueOf(v1[1]);
      int n2 = Integer.valueOf(v2[1]);

      // compare each and get the result
      int r1 = v1[0].compareTo(v2[0]);
      int r2 = Integer.compare(n1,n2);

      // first sort on r1 (the strings).  If they are equal ( r1 == 0) 
      // then sort on the result of comparing the integers.
      return r1 == 0 ? r2 : r1;
};

Array.sort does not take a comparator so you need to convert the array to a list and sort on that. This will also change the array since object arrays back up the returned list from Arrays.asList.

      
Collections.sort(Arrays.asList(var),comp);
System.out.println(Arrays.toString(var)); 

Prints

[a2, a3, a11, b1, b2, b3, c2, c3, c13]
WJS
  • 36,363
  • 4
  • 24
  • 39