#java #collections #java-stream #spotify-docker-client
Вопрос:
Привет, у меня есть коллекция потоков, и я отсортировал ее по дате создания, мне нужно удалить все элементы из этой коллекции, но меньше окончательного:
Это мой код:
List<com.spotify.docker.client.messages.Image> response = dockerClient.listImages()
.stream()
.filter(image -> image.labels() != null amp;amp; image.labels().containsKey("wantedLabel"))
.sorted((o1, o2) -> o2.created().compareTo(o1.created()))
.collect(
Collectors.toList());
В этом списке мои элементы отсортированы по дате создания, и мне нужно удалить все элементы, за исключением последнего.
я попробовал что-то вроде:
if (response.stream().iterator().hasNext()) {
response.remove(count);
count ;
}
Но мне хотелось чего-нибудь более изысканного, спасибо!
Комментарии:
1. Не можете ли вы создать новый список, в котором есть только последний элемент, как в
List.of(response.get(response.size() - 1)
или аналогичный?2. Мне нужно использовать dockerClient.removeImage(image.id()); чтобы удалить все изображения докера за вычетом последнего
Ответ №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
.
Комментарии:
1. Если, как было предложено в вашем другом вопросе,
created()
на самом деле возвращает строку, содержащую число, замените строкуif(toRemove.created().compareTo(mostRecent.created()) > 0) …
наif(Integer.parseInt(toRemove.created()) < Integer.parseInt(mostRecent.created())) …
Ответ №2:
Похоже, что необходимо извлечь изображение с последней created
датой, поэтому Collectors::maxBy
его можно использовать вместо сортировки списка и удаления ненужных элементов:
Image latestImage = dockerClient.listImages()
.stream()
.filter(image -> image.labels() != null amp;amp; 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 amp;amp; 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 amp;amp; 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()))
);
Комментарии:
1. Мне нужно удалить из docker все изображения, за исключением самого последнего, по этой причине мне нужны все старые изображения, просто чтобы использовать dockerClient.removeImage(image.id()) и удалите изображение по его идентификатору
2. @rasilvap вы можете проверить обновление