457

I have a List of doubles in java and I want to sort ArrayList in descending order.

Input ArrayList is as below:

List<Double> testList = new ArrayList();

testList.add(0.5);
testList.add(0.2);
testList.add(0.9);
testList.add(0.1);
testList.add(0.1);
testList.add(0.1);
testList.add(0.54);
testList.add(0.71);
testList.add(0.71);
testList.add(0.71);
testList.add(0.92);
testList.add(0.12);
testList.add(0.65);
testList.add(0.34);
testList.add(0.62);

The out put should be like this

0.92
0.9
0.71
0.71
0.71
0.65
0.62
0.54
0.5
0.34
0.2
0.12
0.1
0.1
0.1
Didier L
  • 18,905
  • 10
  • 61
  • 103
Himanshu
  • 4,751
  • 2
  • 15
  • 16

21 Answers21

665
Collections.sort(testList);
Collections.reverse(testList);

That will do what you want. Remember to import Collections though!

Here is the documentation for Collections.

Carl Walsh
  • 6,100
  • 2
  • 46
  • 50
tckmn
  • 57,719
  • 27
  • 114
  • 156
  • 74
    Maybe it's worth mentioning that you can define your own `Comparator` :) – Polygnome Apr 27 '13 at 12:53
  • 1
    @Polygnome The OP is only sorting `Double`s. – tckmn Apr 27 '13 at 12:54
  • 5
    Yes, but you could sort them in various ways, depending on the use case. Sometimes you might want to sort them by distance to 0. I don't even know about the runtime characteristics of `reverse`, but sorting descending could actually be faster then sorting ascending and then reversing. Moreover, using a List implementation that supports `Comparator` as constructor argument (thus keeping it invariant) would ensure the list is sorted at all times. – Polygnome Apr 27 '13 at 12:58
  • Old post of course, but to sort a list of objects, one must have a CompareTo method defined, similar to using Arrays.sort, I assume? – Ayesha Jan 13 '14 at 22:42
  • 4
    @Ayesha Yes, `Collections.sort` uses `compareTo` behind the scenes. – tckmn Jan 13 '14 at 22:44
  • 57
    One should actually use `Collections.sort(list, Collections.reverseOrder());`. Apart from being more idiomatic (and possibly more efficient), using the reverse order comparator makes sure that the sort is *stable* (meaning that the order of elements will not be changed when they are equal according to the comparator, whereas reversing will change the order). – Marco13 Aug 30 '14 at 23:18
  • Does it return a new array list or should i use the same one? – Kaveesh Kanwal Jan 10 '17 at 10:32
  • It might be worth mentioning that this sort IS case sensitive. Uppercase A-Z then lowercase a-z – jasonleonhard Aug 09 '17 at 00:09
  • In 2019, this answer is harfmul and outdated. Don't do this! – ZhekaKozlov Feb 18 '19 at 12:34
  • What about sorting array? – Jack Apr 07 '22 at 18:55
  • @Jack - you can use java.util.Arrays.sort(arr) – Akhil May 29 '22 at 20:03
177

Descending:

Collections.sort(mArrayList, new Comparator<CustomData>() {
    @Override
    public int compare(CustomData lhs, CustomData rhs) {
        // -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
        return lhs.customInt > rhs.customInt ? -1 : (lhs.customInt < rhs.customInt) ? 1 : 0;
    }
});
zb226
  • 9,586
  • 6
  • 49
  • 79
최봉재
  • 4,039
  • 3
  • 16
  • 21
  • 1
    What should I do if `CustomData ` is `List` which `AnotherModel` has `id` and I want to sort by `id`? And I just access to `CustomData ` model in my class. – Dr.jacky Dec 26 '17 at 11:48
  • 2
    You'd just replace the CustomData class with AnotherModel and have a line like this : return lhs.id > rhs.id ? -1 : .. etc – user2808054 Jan 12 '18 at 17:54
  • 1
    The compare return statement can be better written as `Integer.compare(rhs.customInt, lhs.customInt);` – LordKiz Aug 13 '19 at 09:30
153

For your example, this will do the magic in Java 8

List<Double> testList = new ArrayList();
testList.sort(Comparator.naturalOrder());

But if you want to sort by some of the fields of the object you are sorting, you can do it easily by:

testList.sort(Comparator.comparing(ClassName::getFieldName));

or

 testList.sort(Comparator.comparing(ClassName::getFieldName).reversed());

or

 testList.stream().sorted(Comparator.comparing(ClassName::getFieldName).reversed()).collect(Collectors.toList());

Sources: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

Jonathan Benn
  • 2,908
  • 4
  • 24
  • 28
krmanish007
  • 6,749
  • 16
  • 58
  • 100
  • Where is 'comparing'-method located? – lippo Oct 04 '16 at 10:20
  • 1
    you need to import: import static java.util.Comparator.comparing; – krmanish007 Oct 04 '16 at 13:20
  • 1
    It is available with Java 1.7? – lippo Oct 05 '16 at 11:07
  • 5
    No, this is a part of stream and functional interface, which is all part of Java 8 – krmanish007 Oct 05 '16 at 14:01
  • What type is your `testList`? I can't see a zero-arg `sort()` on `List<>` or `Iterable<>`. – charles-allen Oct 08 '18 at 05:50
  • 1
    You are right @AjahnCharles. They have removed zero-arg, so I have updated my answer now. – krmanish007 Oct 08 '18 at 19:40
  • @krmanish007 - `Comparator.naturalOrder()` is a welcome replacement!! Good knowledge :) – charles-allen Oct 09 '18 at 07:00
  • What's great about the `testList.stream().sorted` is that it creates a sorted _copy_ of the list in a single line. This is handy if you don't want to change the order of the original list – Jonathan Benn Nov 05 '18 at 21:03
  • The `stream()` example requires `.collect(Collectors.toList())` at the end to complete the operation. – Jonathan Benn Nov 05 '18 at 21:05
  • you are right @JonathanBenn, but I am not returning any particular type, so in this case, it will return stream. My idea was to show the different ways of doing the sorting on a list. Regarding your comment about `testList.stream().sorted`, it is more useful if you are doing a few other operations other than sorting, then you can open a stream and do it together, rather than doing it in two different operations. – krmanish007 Nov 05 '18 at 21:57
95

Use util method of java.util.Collections class, i.e

Collections.sort(list)

In fact, if you want to sort custom object you can use

Collections.sort(List<T> list, Comparator<? super T> c) 

see collections api

Elazar
  • 20,415
  • 4
  • 46
  • 67
M Sach
  • 33,416
  • 76
  • 221
  • 314
66

Using lambdas (Java8), and stripping it down to the barest of syntax (the JVM will infer plenty in this case), you get:

Collections.sort(testList, (a, b) -> b.compareTo(a));

A more verbose version:

// Implement a reverse-order Comparator by lambda function
Comparator<Double> comp = (Double a, Double b) -> {
    return b.compareTo(a);
};

Collections.sort(testList, comp);

The use of a lambda is possible because the Comparator interface has only a single method to implement, so the VM can infer which method is implementing. Since the types of the params can be inferred, they don't need to be stated (i.e. (a, b) instead of (Double a, Double b). And since the lambda body has only a single line, and the method is expected to return a value, the return is inferred and the braces aren't necessary.

cyrus
  • 671
  • 5
  • 5
32

With Java8 there is a default sort method on the List interface that will allow you to sort the collection if you provide a Comparator. You can easily sort the example in the question as follows:

testList.sort((a, b) -> Double.compare(b, a));

Note: the args in the lambda are swapped when passed in to Double.compare to ensure the sort is descending

robjwilkins
  • 5,462
  • 5
  • 43
  • 59
  • To me this is the best answer as it also works for sorting using objects ... example `locationDetails.sort((locationDetailAsc,locationDetailsDsc) -> Long.compare(locationDetailsDsc.getSnapshot().getQuantity(), locationDetailAsc.getSnapshot().getQuantity()));` – Syed Anas Feb 21 '18 at 11:52
  • what type of sort does this method perform? – Rishikrishna Sep 22 '20 at 11:50
30

Here is a short cheatsheet that covers typical cases:

import static java.util.Comparator.comparing;

// sort
list.sort(naturalOrder());

// sort (reversed)
list.sort(reverseOrder());

// sort by field
list.sort(comparing(Type::getField));

// sort by field (reversed)
list.sort(comparing(Type::getField).reversed());

// sort by int field
list.sort(comparingInt(Type::getIntField));

// sort by double field (reversed)
list.sort(comparingDouble(Type::getDoubleField).reversed());

// sort by nullable field (nulls last)
list.sort(comparing(Type::getNullableField, nullsLast(naturalOrder())));

// two-level sort
list.sort(comparing(Type::getField1).thenComparing(Type::getField2));
lukas84
  • 428
  • 3
  • 16
ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
27

You can use Collections.sort(list) to sort list if your list contains Comparable elements. Otherwise I would recommend you to implement that interface like here:

public class Circle implements Comparable<Circle> {}

and of course provide your own realization of compareTo method like here:

@Override
    public int compareTo(Circle another) {
        if (this.getD()<another.getD()){
            return -1;
        }else{
            return 1;
        }
    }

And then you can again use Colection.sort(list) as now list contains objects of Comparable type and can be sorted. Order depends on compareTo method. Check this https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html for more detailed information.

Yuriy Vasylenko
  • 3,031
  • 25
  • 25
12

Collections.sort allows you to pass an instance of a Comparator which defines the sorting logic. So instead of sorting the list in natural order and then reversing it, one can simply pass Collections.reverseOrder() to sort in order to sort the list in reverse order:

// import java.util.Collections;
Collections.sort(testList, Collections.reverseOrder());

As mentioned by @Marco13, apart from being more idiomatic (and possibly more efficient), using the reverse order comparator makes sure that the sort is stable (meaning that the order of elements will not be changed when they are equal according to the comparator, whereas reversing will change the order)

Matt
  • 17,290
  • 7
  • 57
  • 71
9
//Here is sorted List alphabetically with syncronized

package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

/**
 * @author manoj.kumar
 */
public class SynchronizedArrayList {
    static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {

        List<Employee> synchronizedList = Collections.synchronizedList(new ArrayList<Employee>());
        synchronizedList.add(new Employee("Aditya"));
        synchronizedList.add(new Employee("Siddharth"));
        synchronizedList.add(new Employee("Manoj"));
        Collections.sort(synchronizedList, new Comparator() {
            public int compare(Object synchronizedListOne, Object synchronizedListTwo) {
                //use instanceof to verify the references are indeed of the type in question
                return ((Employee) synchronizedListOne).name
                        .compareTo(((Employee) synchronizedListTwo).name);
            }
        }); 
    /*for( Employee sd : synchronizedList) {
    log.info("Sorted Synchronized Array List..."+sd.name);
    }*/

        // when iterating over a synchronized list, we need to synchronize access to the synchronized list
        synchronized (synchronizedList) {
            Iterator<Employee> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Sorted Synchronized Array List Items: " + iterator.next().name);
            }
        }

    }
}

class Employee {
    String name;

    Employee(String name) {
        this.name = name;

    }
}
Hitesh sapra
  • 248
  • 2
  • 12
6

You can do like this:

List<String> yourList = new ArrayList<String>();
Collections.sort(yourList, Collections.reverseOrder());

Collection has a default Comparator that can help you with that.

Also, if you want to use some Java 8 new features, you can do like that:

List<String> yourList = new ArrayList<String>();
yourList = yourList.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());
svarog
  • 9,477
  • 4
  • 61
  • 77
Thiago
  • 864
  • 1
  • 9
  • 16
5

if you are using Java SE 8, then this might be of help.

//create a comparator object using a Lambda expression
Comparator<Double> compareDouble = (d1, d2) -> d1.compareTo(d2);

//Sort the Collection in this case 'testList' in reverse order
Collections.sort(testList, Collections.reverseOrder(compareDouble));

//print the sorted list using method reference only applicable in SE 8
testList.forEach(System.out::println);
  • 6
    There is also `Collections.reverseOrder()` without any arguments, which makes your implementation of `compareDouble` superfluous (it's equivalent to the natural ordering of `Double`s). The answer here should be `Collections.sort(testList, Collections.reverseOrder());` – Matt May 13 '15 at 09:23
5

|*| Sorting an List :

import java.util.Collections;

|=> Sort Asc Order :

Collections.sort(NamAryVar);

|=> Sort Dsc Order :

Collections.sort(NamAryVar, Collections.reverseOrder());

|*| Reverse the order of List :

Collections.reverse(NamAryVar);
Sujay U N
  • 4,974
  • 11
  • 52
  • 88
5

In JAVA 8 its much easy now.

List<String> alphaNumbers = Arrays.asList("one", "two", "three", "four");
List<String> alphaNumbersUpperCase = alphaNumbers.stream()
    .map(String::toUpperCase)
    .sorted()
    .collect(Collectors.toList());
System.out.println(alphaNumbersUpperCase); // [FOUR, ONE, THREE, TWO]

-- For reverse use this

.sorted(Comparator.reverseOrder())
IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
Appesh
  • 374
  • 4
  • 6
4

You can use like that

ArrayList<Group> groupList = new ArrayList<>();
Collections.sort(groupList, Collections.reverseOrder());
Collections.reverse(groupList);
svarog
  • 9,477
  • 4
  • 61
  • 77
manikant gautam
  • 3,521
  • 1
  • 17
  • 27
3

For example I have a class Person: String name, int age ==>Constructor new Person(name,age)

import java.util.Collections;
import java.util.ArrayList;
import java.util.Arrays;


public void main(String[] args){
    Person ibrahima=new Person("Timera",40);
    Person toto=new Person("Toto",35);
    Person alex=new Person("Alex",50);
    ArrayList<Person> myList=new ArrayList<Person>
    Collections.sort(myList, new Comparator<Person>() {
        @Override
        public int compare(Person p1, Person p2) {
            // return p1.age+"".compareTo(p2.age+""); //sort by age
            return p1.name.compareTo(p2.name); // if you want to short by name
        }
    });
    System.out.println(myList.toString());
    //[Person [name=Alex, age=50], Person [name=Timera, age=40], Person [name=Toto, age=35]]
    Collections.reverse(myList);
    System.out.println(myList.toString());
    //[Person [name=Toto, age=35], Person [name=Timera, age=40], Person [name=Alex, age=50]]

}
Ibrahima Timera
  • 598
  • 4
  • 7
3

If you have to sort object based on its id in the ArrayList , then use java8 stream.

 List<Person> personList = new ArrayList<>();

    List<Person> personListSorted =
                personList.stream()
                  .sorted(Comparator.comparing(Person::getPersonId))
                  .collect(Collectors.toList());
Afsar Ali
  • 555
  • 6
  • 17
1

With Eclipse Collections you could create a primitive double list, sort it and then reverse it to put it in descending order. This approach would avoid boxing the doubles.

MutableDoubleList doubleList =
    DoubleLists.mutable.with(
        0.5, 0.2, 0.9, 0.1, 0.1, 0.1, 0.54, 0.71,
        0.71, 0.71, 0.92, 0.12, 0.65, 0.34, 0.62)
        .sortThis().reverseThis();
doubleList.each(System.out::println);

If you want a List<Double>, then the following would work.

List<Double> objectList =
    Lists.mutable.with(
        0.5, 0.2, 0.9, 0.1, 0.1, 0.1, 0.54, 0.71,
        0.71, 0.71, 0.92, 0.12, 0.65, 0.34, 0.62)
        .sortThis(Collections.reverseOrder());
objectList.forEach(System.out::println);

If you want to keep the type as ArrayList<Double>, you can initialize and sort the list using the ArrayListIterate utility class as follows:

ArrayList<Double> arrayList =
    ArrayListIterate.sortThis(
            new ArrayList<>(objectList), Collections.reverseOrder());
arrayList.forEach(System.out::println);

Note: I am a committer for Eclipse Collections.

bruno
  • 2,213
  • 1
  • 19
  • 31
Donald Raab
  • 6,458
  • 2
  • 36
  • 44
0

The following line should do the thick

testList.sort(Collections.reverseOrder());
Ivan Kovtun
  • 645
  • 1
  • 11
  • 18
0
  yearList = arrayListOf()
    for (year in 1950 until 2021) {
        yearList.add(year)
    }

   yearList.reverse()
    val list: ArrayList<String> = arrayListOf()

    for (year in yearList) {
        list.add(year.toString())
    }
Caner Yılmaz
  • 201
  • 3
  • 6
0

An alternative way to order a List is using the Collections framework;

in this case using the SortedSet (the bean in the list should implement Comparable, so Double is ok):

List<Double> testList;
...
SortedSet<Double> sortedSet= new TreeSet<Double>();
for(Double number: testList) {
   sortedSet.add(number);
}
orderedList=new ArrayList(sortedSet);

In general, to order by an attribute of a bean in the list,put all the elements of the list in a SortedMap, using as a key the attribute, then get the values() from the SortedMap (the attribute should implement Comparable):

List<Bean> testList;
...
SortedMap<AttributeType,Bean> sortedMap= new TreeMap<AttributeType, Bean>();
for(Bean bean : testList) {
   sortedMap.put(bean.getAttribute(),bean);
}
orderedList=new ArrayList(sortedMap.values());
Bruno F
  • 31
  • 3