patternjavaMinor
Custom sorting of dates
Viewed 0 times
customsortingdates
Problem
I have implemented a class which implements a list of my custom
The custom sort class:
Initially I had implemented it using Comparators but the Lambda made the code much cleaner.
D
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 list = new ArrayList<>();
public static void main(String a[]){
createRandomDateObjs();
Integer CURRENTMONTH = 6;
//Sort Months Descending
Collections.sort(list,(arg0,arg1)-> arg1.getMonth().compareTo(arg0.getMonth()));
//Sort by keeping the object with nearest largest next month first
Collections.sort(list,(arg0,arg1)->CURRENTMONTH.compareTo(arg0.getMonth()));
//Sort the months which were pushed back in an ascending order.
Collections.sort(list,(arg0,arg1)->(arg0.getMonth()(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<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<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.
D
Solution
A
Add
EDIT: An alternative approach is to simply define the
Thanks to Mr.Wiggles for the recommendation.
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{
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)->{
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.
Code Snippets
//Custom Date Object
class DateObj implements Comparable<DateObj>{
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;
}
}
}Collections.sort(list, (o1,o2)->{
int months = (o1.getMonth()+(12-CURRENTMONTH))%12 - (o2.getMonth()+(12-CURRENTMONTH))%12;
if(months == 0)
return o1.getDate()-o2.getDate();
else{
return months;
}
});Context
StackExchange Code Review Q#117757, answer score: 6
Revisions (0)
No revisions yet.