Himanshu
Himanshu

Reputation: 4961

How to sort a List/ArrayList?

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

Upvotes: 478

Views: 1393746

Answers (21)

Donald Raab
Donald Raab

Reputation: 6706

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

Updated: Sept. 2023

Since the 10.3 release, Eclipse Collections supports indirect sorting of primitive lists.

@Test
public void sortDoubleListInDescendingOrder()
{
    MutableDoubleList testList = 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);

    DoubleList expected = DoubleLists.mutable
            .with(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);

    Assertions.assertNotEquals(expected, testList);

    testList.sortThis((i, j) -> -Double.compare(i, j));

    Assertions.assertEquals(expected, testList);
}

End Update

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.

Upvotes: 1

cyrus
cyrus

Reputation: 711

Using lambdas (Java 8), 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 it's 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.

Upvotes: 70

ZhekaKozlov
ZhekaKozlov

Reputation: 39654

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

Upvotes: 36

Bruno F
Bruno F

Reputation: 41

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

Upvotes: 0

Afsar Ali
Afsar Ali

Reputation: 605

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

Upvotes: 3

Caner Yılmaz
Caner Yılmaz

Reputation: 199

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

Upvotes: 0

Thiago
Thiago

Reputation: 997

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

Upvotes: 6

Manikant Gautam
Manikant Gautam

Reputation: 3591

You can use like that

ArrayList<Group> groupList = new ArrayList<>();
Collections.sort(groupList, Collections.reverseOrder());
Collections.reverse(groupList);

Upvotes: 4

Appesh
Appesh

Reputation: 414

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

Upvotes: 5

user4423251
user4423251

Reputation:

//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;

    }
}

Upvotes: 9

tckmn
tckmn

Reputation: 59343

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

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

Here is the documentation for Collections.

Upvotes: 689

Manish Kumar
Manish Kumar

Reputation: 7189

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

Upvotes: 165

Ivan Kovtun
Ivan Kovtun

Reputation: 703

The following line should do the thick

testList.sort(Collections.reverseOrder());

Upvotes: 0

Ibrahima Timera
Ibrahima Timera

Reputation: 707

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]]

}

Upvotes: 3

최봉재
최봉재

Reputation: 4145

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

Upvotes: 183

Sujay U N
Sujay U N

Reputation: 5350

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

Upvotes: 5

robjwilkins
robjwilkins

Reputation: 5662

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

Upvotes: 32

M Sach
M Sach

Reputation: 34424

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

Upvotes: 96

Matt
Matt

Reputation: 17649

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)

Upvotes: 12

Franklin Okeme
Franklin Okeme

Reputation: 59

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

Upvotes: 5

Yuriy Vasylenko
Yuriy Vasylenko

Reputation: 3171

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.

Upvotes: 27

Related Questions