Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numerically sorting the String Arrays

I already know that we can sort string arrays numerically, by converting them to integer array then using Arrays.sort() or using any comparator.

So my question is if those strings are beyond the limit of integer or long int then how can we sort them. For example consider the following string array:

14829435897932384626433832795
4159265358979323846264338327
1937286535897932384626433832795296523
23746289

in those cases traditional comparator or any sorting method won't work because in turn they use integer (or any other datatype).

like image 948
Sandip Kumar Avatar asked Apr 18 '26 15:04

Sandip Kumar


2 Answers

As suggested by Eran: Convert to BigInteger and do the comparison:

Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        BigInteger bi1 = new BigInteger(o1);
        BigInteger bi2 = new BigInteger(o2);
        return bi1.compareTo(bi2);
    }
});

And because @tobias_k doesn't care about karma:

If you're running Java 8, you can use the many new default methods of the Comparator interface to do it in one line:

Arrays.sort(arr, Comparator.comparing(BigInteger::new))

Just added a counter to the Comparator to see how many times a String was converted to a BigInteger. It counted 10 conversions in my simple run of 4 strings.

This made me think that there might be a performance gain by converting each string once, sorting the BigInteger instances and converting them back. Something like this:

List<BigInteger> list1 = list.stream().map(BigInteger::new)
     .sorted().collect(Collectors.toList());
like image 154
Henrik Aasted Sørensen Avatar answered Apr 21 '26 03:04

Henrik Aasted Sørensen


You can use Arrays.sort(array, comparator)

Arrays.sort(array, Comparator.comparing(BigInteger::new));
  • The comparator can take as parameter a function that maps an object into another one (here String into BigInteger)

With details (from shorter to longer, Intellij will propose you to use 1st one) : :

= Comparator.comparing(BigInteger::new)
= Comparator.comparing(val -> new BigInteger(val))
= Comparator.comparing((o1, o2) -> new BigInteger(o1).compareTo(new BigInteger(o2)))

String[] array = new String[]{"14829435897932384626433832795", 
                              "4159265358979323846264338327", 
                              "1937286535897932384626433832795296523", "23746289"};
Arrays.sort(array, Comparator.comparing(BigInteger::new));
System.out.println(Arrays.toString(array));

//Will result in 
[23746289, 4159265358979323846264338327, 14829435897932384626433832795, 1937286535897932384626433832795296523]
like image 26
azro Avatar answered Apr 21 '26 05:04

azro