I have a list of objects with a string (name) and a local date (date of deletion).
I wish to implement uniqueness on these objects based on:
- If two objects have the same name, then I wish the one with no date of deletion to have priority.
- If two objects have the same name, and a date of deletion, then I wish the one with the most recent date of deletion to have priority.
Based on the above criteria, I have implemented, what I think is the right solution.
Do you have any pointers as to the correctness of my approach? Do you have any suggestions for improvements?
The class:
public class Unique implements Comparable<Unique>
{
private String name;
private LocalDate dateOfDeletion;
public Unique(String name, LocalDate dateOfDeletion) {
this.name = name;
this.dateOfDeletion = dateOfDeletion;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getDateOfDeletion() {
return dateOfDeletion;
}
public void setDateOfDeletion(LocalDate dateOfDeletion) {
this.dateOfDeletion = dateOfDeletion;
}
@Override
public String toString() {
return "Unique [name=" +name + ", dateOfDeletion="+dateOfDeletion+"],";
}
/**
* order based on name ascending, and date descending
*/
@Override
public int compareTo(Unique rhs) {
Comparator<Unique> reverseDateComparator = (a, b) -> {
LocalDate thisDodel = a.getDateOfDeletion() == null ? LocalDate.now().plusDays(1) : a.getDateOfDeletion();
LocalDate thatDodel = b.getDateOfDeletion() == null ? LocalDate.now().plusDays(1) : b.getDateOfDeletion();
return thatDodel.compareTo(thisDodel);
};
return Comparator.comparing(Unique::getName).thenComparing(reverseDateComparator).compare(this, rhs);
}
}
The Test:
public static void main(String[] args) {
List<Unique> uniqueList = Arrays.asList(
new Unique("a", null)
,new Unique("b", null)
,new Unique("b", LocalDate.of(2016, Month.SEPTEMBER, 20))
,new Unique("c", LocalDate.of(2016, Month.SEPTEMBER, 19))
,new Unique("c", LocalDate.of(2016, Month.SEPTEMBER, 20))
);
System.out.println("list ordered, with duplicates: ");
uniqueList.stream().sorted().forEach(System.out::println);
System.out.println("=================");
System.out.println("list ordered, duplicates removed: ");
Comparator<Unique> uniqueComp = (a, b) -> a.getName().compareTo( b.getName() );
//SOLUTION HERE: since list is already ordered by date desc, it will ignore the records with same name already added to the list
TreeSet<Unique> sortedFilterd = uniqueList.stream().sorted().collect(Collectors.toCollection(() -> new TreeSet<Unique>(uniqueComp)));
sortedFilterd.forEach(System.out::println);
}
What I expect to see is the following:
list ordered, with duplicates:
Unique [name=a, dateOfDeletion=null],
Unique [name=b, dateOfDeletion=null],
Unique [name=b, dateOfDeletion=2016-09-20],
Unique [name=c, dateOfDeletion=2016-09-20],
Unique [name=c, dateOfDeletion=2016-09-19],
=================
list ordered, duplicates removed:
Unique [name=a, dateOfDeletion=null],
Unique [name=b, dateOfDeletion=null],
Unique [name=c, dateOfDeletion=2016-09-20],
Here is a link to the working sample: Link to working sample to the above code