Найти максимум из нескольких списков - PullRequest
5 голосов
/ 16 апреля 2020

Я довольно новичок в java потоках и пытаюсь определить, как найти максимум из каждого списка, в списке списков, и заканчиваю одним списком, который содержит максимум из каждого подсписка.

Я могу выполнить это sh, используя for l oop и stream примерно так:

// databaseRecordsLists is a List<List<DatabaseRecord>>

List<DatabaseRecord> mostRecentRecords = new ArrayList<>();

for (List<DatabaseRecord> databaseRecords : databaseRecordsLists) {
            mostRecentRecords.add(databaseRecords.stream()
                    .max(Comparator.comparing(DatabaseRecord::getTimestamp))
                    .orElseThrow(NoSuchElementException::new));
        }

Я посмотрел на API flatMap, но затем я Я получу только одну карту из всех DatabaseRecord объектов, где мне нужно максимум из каждого отдельного списка.

Есть идеи по более чистому способу выполнения sh этого?

Ответы [ 2 ]

5 голосов
/ 16 апреля 2020

Вам не нужно flatMap. Создайте Stream<List<DatabaseRecord>> и сопоставьте каждый List<DatabaseRecord> из Stream с элементом max. Затем соберите все элементы max на выходе List.

List<DatabaseRecord> mostRecentRecords =
    databaseRecordsLists.stream()
                        .map(list -> list.stream()
                                         .max(Comparator.comparing(DatabaseRecord::getTimestamp))
                                         .orElseThrow(NoSuchElementException::new))
                        .collect(Collectors.toList());
4 голосов
/ 16 апреля 2020

Исходя из комментариев, я предложил скорее игнорировать пустую коллекцию, иначе результат не будет возвращен и NoSuchElementException выбросит даже пустую коллекцию может (?) Быть действительным состоянием. Если это так, вы можете улучшить текущее решение:

databaseRecordsLists.stream()
    .filter(list -> !list.isEmpty())                              // Only non-empty ones
    .map(list -> list.stream()     
         .max(Comparator.comparing(DatabaseRecord::getTimestamp)) // Get these with max
         .orElseThrow(NoSuchElementException::new))               // Never happens
    .collect(Collectors.toList());                                // To List

Если вы используете версию выше Java 8:

  • По состоянию на Java 10, orElseThrow(NoSuchElementException::new) можно заменить на orElseThrow().
  • Начиная с Java 11, вы можете использовать Predicate.not(..), поэтому часть фильтра будет выглядеть следующим образом: .filter(Predicate.not(List::isEmpty)).
...