Sandip Kumar
Sandip Kumar

Reputation: 271

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).

Upvotes: 2

Views: 951

Answers (3)

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());

Upvotes: 9

Juan Carlos Mendoza
Juan Carlos Mendoza

Reputation: 5794

You can also create a custom comparator:

List<String> list = Arrays.asList("14829435897932384626433832795", "4159265358979323846264338327", "1937286535897932384626433832795296523", "23746289", "4159265358979323846264338326");

// comparing by String if the length is equal
Collections.sort(list, Comparator.comparingInt(String::length).thenComparing(String::compareTo));

System.out.println(list);

Output:

[23746289, 4159265358979323846264338326, 4159265358979323846264338327, 14829435897932384626433832795, 1937286535897932384626433832795296523]

Upvotes: 3

azro
azro

Reputation: 54148

You can use Arrays.sort(array, comparator)

Arrays.sort(array, Comparator.comparing(BigInteger::new));

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]

Upvotes: 8

Related Questions