0

嗨,我有一个流集合,我按创建日期对其进行了排序,我需要从这个集合中删除所有元素,但最后一个元素要少:

这是我的代码:

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++;
 }

但我想要更复杂的东西,谢谢!

4

2 回答 2

2

使用传统循环可以简单高效地解决此任务:

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

于 2021-09-29T18:16:44.057 回答
0

似乎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()))
    );
于 2021-09-28T19:14:42.623 回答