Я использую Google Cloud Java API для получения объектов из облачного хранилища Google (GCS). Код для этого читает что-то вроде этого:Lazily recurse Java 8 stream
Storage storage = ...
List<StorageObject> storageObjects = storage.objects().list(bucket).execute().getItems();
Но это не вернет все элементы (объекты хранения) в ведре ГКС, он будет возвращать только первые 1000 пунктов в первой «страницы». Поэтому для того, чтобы получить следующий 1000 пунктов нужно сделать:
Storage.Objects.List list = storage.objects().list(bucket).execute();
String nextPageToken = objects.getNextPageToken();
List<StorageObject> itemsInFirstPage = objects.getItems();
if (nextPageToken != null) {
// recurse
}
То, что я хочу сделать, это найти элемент, который соответствует Predicate
при обходе всех элементов в ведре ГКС, пока предикат не соответствует. Чтобы сделать это эффективным, я хотел бы загружать только элементы на следующей странице, когда элемент не был найден на текущей странице. Для одной страницы это работает:
Predicate<StorageObject> matchesItem = ...
takeWhile(storage.objects().list(bucket).execute().getItems().stream(), not(matchesItem));
Где takeWhile
копируется из here.
И это будет загружать объекты хранения со всех страниц рекурсивно:
private Stream<StorageObject> listGcsPageItems(String bucket, String pageToken) {
if (pageToken == null) {
return Stream.empty();
}
Storage.Objects.List list = storage.objects().list(bucket);
if (!pageToken.equals(FIRST_PAGE)) {
list.setPageToken(pageToken);
}
Objects objects = list.execute();
String nextPageToken = objects.getNextPageToken();
List<StorageObject> items = objects.getItems();
return Stream.concat(items.stream(), listGcsPageItems(bucket, nextPageToken));
}
где FIRST_PAGE
просто «магия» String
что инструктирует метод не устанавливать конкретную страницу (которая приведет к первой странице Предметы).
Проблема с этим подходом заключается в том, что он стремится, то есть все элементы со всех страниц загружаются до применения «подходящего предиката». Я бы хотел, чтобы это было ленивым (по одной странице за раз). Как я могу это достичь?
Я закончил с использованием второго подхода, работает как шарм. – Johan