【问题标题】:How to remove the last element from a Stream Collection (DockerClient)如何从流集合中删除最后一个元素(DockerClient)
【发布时间】:2021-11-20 19:33:42
【问题描述】:

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

这是我的代码:

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

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

【问题讨论】:

  • 你不能创建一个只包含List.of(response.get(response.size() - 1) 或类似的最后一个元素的新列表吗?
  • 我需要使用 dockerClient.removeImage(image.id());删除所有 docker 图像,减去最后一个

标签: java collections java-stream spotify-docker-client


【解决方案1】:

这个任务可以用传统的循环简单而高效地解决:

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() 实际上返回一个包含数字的字符串,请将@​​987654324@ 行替换为if(Integer.parseInt(toRemove.created()) &lt; Integer.parseInt(mostRecent.created())) …
【解决方案2】:

似乎需要检索具有最新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()))
    );

【讨论】:

  • 我需要从 docker 中删除所有图像,而不是最近的图像,因此我需要所有旧图像,只需使用 dockerClient.removeImage(image.id()) 并删除图像的 ID
  • @rasilvap 你可以检查更新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 2014-12-09
  • 2014-11-28
  • 2013-10-28
  • 1970-01-01
  • 2020-02-19
  • 2012-01-05
相关资源
最近更新 更多