嗨,我有一个流集合,我按日期创建排序,我需要从这个集合中删除所有元素,但少了最后一个:
这是我的代码:
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());
在这个列表我元素按创建日期和我需要删除所有的最后一个元素少。
我试过这样做:
if (response.stream().iterator().hasNext()) {
response.remove(count);
count++;
}
但是我想要一些更复杂的东西,谢谢!
这个任务可以用传统的循环简单有效地解决:
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());
}
}
这个循环遍历图像,一旦找到最近的匹配对象就删除图像,不需要额外的存储和排序。当循环完成时,除了最近的匹配图像之外的所有图像都被删除,并且作为奖励,保留的最新对象保存在变量mostRecent
中。
似乎需要检索具有最新created
日期的图像,因此可以使用Collectors::maxBy
而不是对列表进行排序并删除不需要的元素:
Image latestImage = dockerClient.listImages()
.stream()
.filter(image -> image.labels() != null && image.labels().containsKey("wantedLabel"))
.collect(Collectors.maxBy(Image::created)) // Optional<Image>
.orElse(null);
如果真的需要有一个List
作为结果:
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());
更新
一旦找到最新的镜像,如果有必要,可以使用forEach
从Docker容器中删除镜像:
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()))
);