EDIT: The approach shown here might be seen as an abuse of the Stream.map
operation, even though in practice it will always work (with the caveat of the final note at the end of the initial version of the post).
Please refer to the addendum for a cleaner approach.
It's not necessary to do any sorting (which is a O(NlogN)
operation), when all you have to do is find the element with the max date.
You could stream the list of MyObject
elements, deactivate all of them, then find the element with the max date and finally activate it:
myList.stream()
.map(myObject -> { myObject.setActive("0"); return myObject; })
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(myObject -> myObject.setActive("1"));
This code would read much better if the MyObject
class would have fluent methods to set the active
property:
public MyObject activated() {
active = "1";
return this;
}
public MyObject deactivated() {
active = "0";
return this;
}
Now the solution would become:
myList.stream()
.map(MyObject::deactivated)
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(MyObject::activated);
Note: this approach might not work if the source of the stream reports itself as sorted. As you're using a list, this won't happen.
Addendum:
As discussed in the comments, the cleanest approach would be to set all the elements to inactive, then find the element with the max date and set it to active:
myList.forEach(myObject -> myObject.setActive("0"));
myList.stream()
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(myObject -> myObject.setActive("1"));
Or using the fluent methods:
myList.forEach(MyObject::deactivated);
myList.stream()
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(MyObject::activated);
Of course, this approach requires 2 passes over the list, but it clearly shows the intention of the developer and doesn't abuse the stream API.
A variant of this last snippet could be:
myList.forEach(MyObject::deactivated);
if (!myList.isEmpty())
Collections.max(myList, Comparator.comparing(MyObject::getDate))
.activated();