Custom sorting of dates I have implemented a class which implements a list of my custom DateObj. I have sorted the list in a peculiar manner based on the current month. I achieved my desired results, but I'm required to call Collections.sort() four times to achieve it. I feel this could be improved. Any thoughts?

//Custom Date Object
public class DateObj {

private int year;
private int month;
private int date;

DateObj(int year, int month ,int date){
    this.year = year;
    this.month = month;
    this.date = date;
}

public Integer getYear() {return year;}
public Integer getMonth() {return month;}
public Integer getDate() {return date;}
}


The custom sort class:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CustomListSort {
 static List&lt;DateObj&gt; list = new ArrayList&lt;&gt;();

public static void main(String a[]){

createRandomDateObjs();

Integer CURRENTMONTH = 6;

//Sort Months Descending
Collections.sort(list,(arg0,arg1)-&gt; arg1.getMonth().compareTo(arg0.getMonth()));

//Sort by keeping the object with nearest largest next month first
Collections.sort(list,(arg0,arg1)-&gt;CURRENTMONTH.compareTo(arg0.getMonth()));

//Sort the months which were pushed back in an ascending order.
Collections.sort(list,(arg0,arg1)-&gt;(arg0.getMonth()&lt;=CURRENTMONTH &amp;&amp; arg1.getMonth()&lt;=CURRENTMONTH)? arg0.getMonth().compareTo(arg1.getMonth()):0);

//If months same sort them in ascending manner based on their dates
Collections.sort(list, (arg0,arg1)-&gt;(arg0.getMonth() == arg1.getMonth())  ? arg0.getDate().compareTo(arg1.getDate()) : 0);

System.out.println("\nDESIRED OUTPUT");
System.out.println("\nMM - DD - YYYY \n");

for(int i = 0 ; i&lt;list.size();i++)
    System.out.println(list.get(i).getMonth() +" - "+list.get(i).getDate()+" - "+list.get(i).getYear());        
}

static void createRandomDateObjs(){
    for(int i = 0 ; i&lt;20 ; i++){
        int y = 1980;
            y+=(int)(Math.random()*55);
        int m = (int) (Math.random()*11);
        int d = (int) (Math.random()*30);
        list.add(new DateObj(++y,++m,++d)); //Pre-increment to change 0's to 1's
}
}


Initially I had implemented it using Comparators but the Lambda made the code much cleaner.

Desired output:


MM - DD - YYYY 

7 - 20 - 2023
7 - 18 - 2027
8 - 30 - 2010
8 - 12 - 2020
9 - 21 - 2006
10 - 23 - 2008
11 - 19 - 2000
11 - 16 - 2033
11 - 13 - 1989
12 - 13 - 2019
1 - 10 - 1985
1 - 15 - 2016
4 - 10 - 2021
4 - 13 - 2022
4 - 14 - 2004
5 - 1 - 2025
5 - 4 - 2014
5 - 20 - 2023
5 - 21 - 2022
6 - 29 - 1990
A Comparator is the correct approach, you just need to mod the month by the current month before comparing them. The easiest way to do this is to introduce a static variable currentMonth to hold the current month for all instances of DateObj.

Add DateObj.setCurrentMonth(CURRENTMONTH); to your Main, and use the code below:

//Custom Date Object
class DateObj implements Comparable&lt;DateObj&gt;{

    private int year;
    private int month;
    private int date;
    private static int currentMonth;

    DateObj(int year, int month ,int date){
      this.year = year;
      this.month = month;
      this.date = date;
    }

    public Integer getYear() {return year;}
    public Integer getMonth() {return month;}
    public Integer getDate() {return date;}
    public Integer getCurrentMonth() { return DateObj.currentMonth;}
    public static void setCurrentMonth(int currentMonth){
        DateObj.currentMonth = currentMonth;
    }

    @Override
    public int compareTo(DateObj o) {
        int months = (month+(12-currentMonth))%12 - (o.month+(12-currentMonth))%12;
        if(months == 0)
            return this.date-o.date;
        else{
            return months;
        }
    }
}


EDIT: An alternative approach is to simply define the Comparator in your main body. This avoids the use a static value to hold currentMonth:

    Collections.sort(list, (o1,o2)-&gt;{
            int months = (o1.getMonth()+(12-CURRENTMONTH))%12 - (o2.getMonth()+(12-CURRENTMONTH))%12;
            if(months == 0)
                return o1.getDate()-o2.getDate();
            else{
                return months;
            }
    });


Thanks to Mr.Wiggles for the recommendation.