I have List of objects any objects have two Date properties insertDate and updateDate I need to find the object that have absolute max between the two properties insertDate and updateDate. Example (Object of the list have properties):
-> insertDate = 2020-10-11 15:48 updateDate = 2020-11-11 15:48
insertDate = null updateDate = 2019-09-11 15:48
insertDate = 2019-10-11 15:48 updateDate = null
insertDate = null updateDate = null
insertDate = 2019-10-11 15:48 updateDate = 2019-11-11 10:48
So the arrow indicated the object of the List which will be removed. I tried different approach:
etc etc..
Important: consider that the Date attribute where we search max can be null
Can somebody have a performance and elegant solution? It's too complicate and I'm not very speedly with lambda ....
Thanks a lot for your support
Here is one possibility. I did this using LocalDateTime, not Date because Date is outdated. The java::time package should be used. I updated my version of your class for demonstration purposes. You will need to subsitute the name of your class with MyObject
for this to work with your data.
The Data.
List<MyObject> list = List.of(
new MyObject("2020-10-11 15:48", "2020-11-11 15:48"),
new MyObject(null, "2019-09-11 15:48"),
new MyObject("2019-10-11 15:48", null),
new MyObject(null, null),
new MyObject("2019-10-11 15:48", "2019-11-11 10:48"));
The Comparator.
Comparator<MyObject> comp = (a,b)->
Long.compare(Duration.between(a.getInsertDate(),a.getUpdateDate())
.toMillis(),
Duration.between(b.getInsertDate(),b.getUpdateDate())
.toMillis());
Now simply stream the list, filter out objects with nulls for any of the times. The result returns the object with maximum duration. If nothing is found, it returns a null.
MyObject result = list.stream()
.filter(obj -> obj.getInsertDate() != null
&& obj.getUpdateDate() != null)
.max(comp).orElse(null);
System.out.println(result);
This prints
2020-10-11 15:48 2020-11-11 15:48
For completon I provided a Date
comparator to use since you have Date
fields in your object. Just substitute the dateComparator
for comp
in the previous stream and it should work just fine.
Comparator<MyObject> dateComparator = (a, b) -> Long.compare(
Math.abs(a.getInsertDate().toInstant().toEpochMilli()-
a.getUpdateDate().toInstant().toEpochMilli()),
Math.abs(b.getInsertDate().toInstant().toEpochMilli()-
b.getUpdateDate().toInstant().toEpochMilli()));
The object class definition.
class MyObject {
public LocalDateTime insertDate;
public LocalDateTime updateDate;
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
public MyObject(String insertDate, String updateDate) {
if (insertDate != null) {
this.insertDate = LocalDateTime.parse(insertDate,dtf);
}
if (updateDate != null) {
this.updateDate = LocalDateTime.parse(updateDate,dtf);
}
}
public LocalDateTime getInsertDate() {
return insertDate;
}
public LocalDateTime getUpdateDate() {
return updateDate;
}
public String toString() {
return insertDate.format(dtf) + " " + updateDate.format(dtf);
}
}