Reputation: 245
I have two date fields in Temp class say validFromDate and asOfDate. I have List with me. I need to set the flag whihc is one of the class attributes to true for the record whose validFromDate is closest to asOfDate
Ex.
List<temp> {
Temp1:
asOfDate: 2018-01-04
validFrom: 2018-01-01
Temp2:
asOfDate: 2018-01-04
validFrom: 2018-01-02
Temp3:
asOfDate: 2018-01-04
validFrom: 2018-01-03
}
o/p should be Temp3 as this validFrom is nearest to asOfdate. I will set the flag to true for this Temp2
How can I achieve this using Java 8 streams?
Upvotes: 3
Views: 5202
Reputation: 521279
We can try sorting your list based on the absolute difference between the asOfDate
and the validFrom
date, then take the first element from the sorted list. Something like this:
list.sort((Temp t1, Temp t2)
->Long.compare(Math.abs(t1.getAsOfDate().getTime() - t1.getValidFrom().getTime()),
Math.abs(t2.getAsOfDate().getTime() - t2.getValidFrom().getTime())));
System.out.println(list.get(0));
This assumes that your dates are the old school pre Java 8 java.util.Date
class. If not, my code would have to change. This also assumes that you are OK with changing the order of the list.
Follow the demo link below which shows that the above lambda sort in fact works on a small set of sample data.
Edit:
If you don't want to alter the original list, but instead want to just update the single matching Temp
element, then you can make a copy of the list and then sort the copy:
List<Temp> copy = new ArrayList<>(list);
// sort copy, per above
// then update the original list
Temp match = copy.get(0);
int index = list.indexOf(match);
list.get(index).setFlag(true);
Upvotes: 0
Reputation: 44150
You can use ChronoUnit.DAYS.between
to calculate the number of days between the dates, then use Stream.min
to get the lowest value:
Optional<MyClass> shortestDate = myList.stream()
.min(
Comparator.comparingLong(
item -> ChronoUnit.DAYS.between(item.asOfDate(), item.validFrom())
)
);
Upvotes: 1
Reputation: 120858
temp.stream()
.map(x -> new SimpleEntry<>(x, ChronoUnit.DAYS.between(x.getAsOfDate(), x.getValidFrom())))
.min(Comparator.comparingLong(Entry::getValue))
.map(Entry::getKey)
.orElse(...);
Or simpler:
test.stream()
.min(Comparator.comparingLong(x -> ChronoUnit.DAYS.between(x.asOfDate , x.validFrom)));
Upvotes: 3