Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort collection with null's and invert the list afterwards?

Tags:

java

null

sorting

So I'm working with a list of Dates and some of the values are "" ie null. I used the answer from How to handle nulls when using Java collection sort

public int compare(MyBean o1, MyBean o2) {
    if (o1.getDate() == null) {
        return (o2.getDate() == null) ? 0 : -1;
    }
    if (o2.getDate() == null) {
        return 1;
    }
    return o2.getDate().compareTo(o1.getDate());
} 

to sort the list in both ascending which puts the nulls first.

What I want is in ascending order to have nulls first and then the values afterwards in ascending order like the above code does. Then when descending is selected to literally flip the list. IE first values in list are in descending order then all the nulls.

I've attempted the following after I sorted the list in ascending order Collections.reverseOrder(); This kept the nulls first and then sorted the dates in descending order.

I also tried Collections.reverse(List). This put the nulls at the end of the list but kept the Dates in ascending order.

like image 396
Jeremy Avatar asked Mar 17 '15 16:03

Jeremy


People also ask

How do I sort a collection in reverse order?

The reverseOrder() method of Collections class that in itself is present inside java. util package returns a comparator and using this comparator we can order the Collection in reverse order. Natural ordering is the ordering imposed by the objects' own compareTo method.

How do I sort a list with null values?

Whenever we try to sort elements with null values using the sort method it throws an exception. The sort() method of the Arrays class also accepts a Comparator along with the array. Using comparator, you need to specify the order in which the elements need to be sorted.

How do you reverse sort in Java?

To sort an array in Java in descending order, you have to use the reverseOrder() method from the Collections class. The reverseOrder() method does not parse the array. Instead, it will merely reverse the natural ordering of the array.


2 Answers

In Java 8 this whole thing can be

Collections.sort(list, 
     Comparator.comparing(MyBean::getDate, 
        Comparator.nullsFirst(Comparator.naturalOrder()))
     .reversed());
like image 87
Louis Wasserman Avatar answered Sep 21 '22 09:09

Louis Wasserman


You can achieve this by a simple comparator. Modify this as per your custom bean object. Something like this -

public class DateComparator implements Comparator<Date> {

    private boolean reverse;

    public DateComparator(boolean reverse) {
        this.reverse = reverse;
    }

    public int compare(Date o1, Date o2) {
        if (o1 == null || o2 == null) {
            return o2 != null ? (reverse ? 1 : -1) : (o1 != null ? (reverse ? -1 : 1) : 0);
        }
        int result = o1.compareTo(o2);
        return reverse ? result * -1 : result;
    }

    public static void main(String[] args) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
        Date[] dates = new Date[]{null, dateFormat.parse("10-10-2013"), null, dateFormat.parse("10-10-2012"), dateFormat.parse("10-10-2015"), dateFormat.parse("10-10-2011"), null};
        List<Date> list = Arrays.asList(dates);
        Collections.sort(list, new DateComparator(false));
        System.out.println(list);
        Collections.sort(list, new DateComparator(true));
        System.out.println(list);
    }
}
like image 31
hemant1900 Avatar answered Sep 21 '22 09:09

hemant1900