Sort an ArrayList of Strings that are numbers

2020-04-05 02:53发布

问题:

What is the fastest way to sort an ArrayList<String> (in descending/ascending manner) that contains numbers, eg: { "12", "3.5", "188", "33.03" } ? Does Collections have a built-in method for this? Currently I am copying the ArrayList's contents to ArrayList<Double> and then using Collections.Sort() method and then putting it back to the initial array. Is there a faster way?

回答1:

You need to implement your own comparator, and use it on your list. You have to use BigDecimal, because you can have problems with loss of precision. You can use double, if your numbers are quire small precision.

class MyComparator implements Comparator<String, String> {

    public int compare(String o1, String o2){
        return new BigDecimal(o1).compareTo(new BigDecimal(o2));
    }

}
...
Collections.sort(list, new MyComparator());


回答2:

If you are using Java 8, you can use Comparator.comparing(Double::parseDouble) to quickly create a comparator using parseDouble. This should (see below) call the function just once for each entry, and not once for each pair.

List<String> list = Arrays.asList( "12", "3.5", "188", "33.03" );
list.sort(Comparator.comparing(Double::parseDouble));
System.out.println(list);

Output:

[3.5, 12, 33.03, 188]

Update: Well, I thought this would call the comparator function just once for each element, like using a key-function in Python, but after a quick test using a function increasing a counter each time it is called, the function is called just as often as using an old-style "pair"-comparator. Still, a bit shorter...



回答3:

I think your current approach is probably fine, I would avoid using a custom Comparator because you would end up converting the same string into a numeric value multiple times (each time the sorting algorithm wants to compare 2 values) rather than just once as you do now.



回答4:

Try following code:

String test[] = {"12", "3.5", "188", "33.03"};
double numbers[] = new double[test.length];
for (int i = 0; i < test.length; i++) {
     numbers[i] = Double.parseDouble(test[i]);
}
Arrays.sort(numbers);
for (double i : numbers) {
     System.out.println(i);
}

Output :

3.5
12.0
33.03
188.0


回答5:

You can use Collections.sort() on List<String>, String is Comparable, but that comparison won't give you the right result.

Also you can define your own Comparator, and pass it to Collections.sort().



回答6:

You can try sortedset interface which enables you the sorted data during the time of entering the data.Better implement your own comparator which will be little beneficial i believe.