Reputation: 2149
Hi I have a stream Collection and I sorted it by the date creation, I need to remove all the elements from this Collections, but less the final one:
This is my code:
List<com.spotify.docker.client.messages.Image> response = dockerClient.listImages()
.stream()
.filter(image -> image.labels() != null && image.labels().containsKey("wantedLabel"))
.sorted((o1, o2) -> o2.created().compareTo(o1.created()))
.collect(
Collectors.toList());
In this list I have my elements sorted by created date and I need to remove all the elements less the final one.
i tried something like:
if (response.stream().iterator().hasNext()) {
response.remove(count);
count++;
}
But I wanted to have something more sophisticated, thanks!
Upvotes: 0
Views: 731
Reputation: 298203
This task can be solved simple and efficient with a traditional loop:
com.spotify.docker.client.messages.Image mostRecent = null;
for(var image: dockerClient.listImages()) {
if(image.labels() == null || !image.labels().containsKey("wantedLabel")) continue;
if(mostRecent == null) mostRecent = image;
else {
var toRemove = image;
if(toRemove.created().compareTo(mostRecent.created()) > 0) {
toRemove = mostRecent;
mostRecent = image;
}
dockerClient.removeImage(toRemove.id());
}
}
This loop iterates over the images and removes an image as soon as a more recent matching object has been found, without the need for additional storage nor sorting. When the loop completes, all but the most recent matching image have been removed and, as a bonus, the retained most recent object is held in the variable mostRecent
.
Upvotes: 2
Reputation: 19545
It seems that an image with the latest created
date needs to be retrieved, therefore Collectors::maxBy
could be used instead of sorting the list and removing unneeded elements:
Image latestImage = dockerClient.listImages()
.stream()
.filter(image -> image.labels() != null && image.labels().containsKey("wantedLabel"))
.collect(Collectors.maxBy(Image::created)) // Optional<Image>
.orElse(null);
If it is really needed to have a List
as result:
List<Image> response = dockerClient.listImages()
.stream()
.filter(image -> image.labels() != null && image.labels().containsKey("wantedLabel"))
.collect(Collectors.maxBy(Image::created)) // Optional<Image>
.map(Collections::singletonList)
.orElseGet(() -> Collections.emptyList());
Update
As soon as the latest image is found, it is possible to use forEach
to delete the images from the Docker container if necessary:
List<Image> images = dockerClient.listImages()
.stream()
.filter(image -> image.labels() != null && image.labels().containsKey("wantedLabel"))
.collect(Collectors.toList());
images.stream()
.collect(Collectors.maxBy(Image::created)) // Optional<Image>
.ifPresent(latest ->
images.stream()
.filter(img -> !latest.getId().equals(img.getId()))
.forEach(img -> dockerClient.removeImage(img.getId()))
);
Upvotes: 0