Java 8:使用集合流按流表示日期以升序方式对集合进行排序

Java 8 : Order a Collection by stream representation date in ascending way using collections streams

我正在使用 DockerClient,我有一个图像集合,我需要删除所有图像,但不是最新的,所以我想按升序对集合进行排序,我有一个创建的字段是一个字符串,日期的数字表示为 1632912516.

我试了下一个:

    public void checkingTest() throws DockerException, InterruptedException {
      try {
      List<com.spotify.docker.client.messages.Image> sortedImages = getImages();

      sortedImages.stream()
          .filter(img -> !img.id().equals(sortedImages.get(sortedImages.size() - 1).id()))
          .forEach(img -> {
            try {
              dockerClient.removeImage(img.id());
            }
            catch (DockerException e) {
              e.printStackTrace();
            }
            catch (InterruptedException e) {
              e.printStackTrace();
            }
          });
    }
    catch (DockerCertificateException e) {
      e.printStackTrace();
    }
  }

  private List<com.spotify.docker.client.messages.Image> getImages()
      throws DockerCertificateException, DockerException, InterruptedException
  {
    final DockerClient dockerClient =
        DefaultDockerClient.fromEnv().connectTimeoutMillis(TimeUnit.SECONDS.toMillis(3)).build();

    return dockerClient.listImages()
        .stream()
        .filter(image -> image.labels() != null && image.labels().containsKey("image"))
        .sorted((o1, o2) -> o2.created().compareTo(o1.created()))
        .collect(
            Collectors.toList());
  }

但是我看到,在 getImages 方法中集合没有排序,所以我想我需要将创建的字段转换为不同的字符串来实现这一点。

有什么想法吗?

sorted() 采用 Comparator,其单一抽象方法是 compare() 而不是 ComparablecompareTo().

如果 listImages 返回的 class 实现了 Comparable,那么您可以使用不带参数的 sorted(),因为 compareTo() 将被调用。但是,compareTo() 的覆盖需要将您正在考虑的任何字段与“最后一个”进行比较(这是按日期?按名称?)。

我还建议,如果您想按时间顺序对信息进行排序,您可以使用 LocalDateTime(或类似的东西)而不是创建 String 并将其用作日期的数字表示。取决于排序实现 Strings,因为数字不会与真实数字(1、10、100、2、20、200)排序相同。从抽象的角度来看,将日期视为日期。

您可以按创建日期降序对事物进行排序,跳过第一个(最新)并删除每个剩余图像:

try{
final DockerClient dockerClient = DefaultDockerClient.fromEnv()
.connectTimeoutMillis(TimeUnit.SECONDS.toMillis(3)).build();
    dockerClient.listImages()
            .stream()
            .filter(image -> image.labels() != null && image.labels().containsKey("image"))
            .sorted(Comparator.comparing(Image::created).reversed()).skip(1)
            .forEach(img -> {
            try {
              dockerClient.removeImage(img.id());
            catch(Exception ex){
              ex.printStackTrace();
            }
            );
}catch (Exception e){
   e.printStackTrace();
}

      

Collections.max()

您无需对所有图片进行排序即可找到最新的。 Collections.max() 可以做到。简化代码来说明我的观点:

    List<Image> unsortedImages = // …;
    if (! unsortedImages.isEmpty()) {
        Id latestId = Collections.max(unsortedImages,
                        Comparator.comparingLong(img -> Long.parseLong(img.created())))
               .id();
         // Proceed with deleting as in your code
    }

我知道 Image.created() returns 一个 String 持有 Unix 时间戳(自 1970 年 Unix 纪元以来的秒数)。