Получить теги книг выбранных авторов

17. Получить теги книг выбранных авторов

Условие задачи:
Необходимо реализовать метод, который получает список авторов и идентификаторы выбранных авторов, а затем возвращает все теги их книг.

Код:

public class Ex {

    public static class Tag {
        String name;

        public Tag(String name) {
            this.name = name;
        }
    }

    public static class Book {
        String name;
        List<Tag> tags;

        public Book(String name, List<Tag> tags) {
            this.name = name;
            this.tags = tags;
        }
    }

    public static class Author {
        String id;
        String name;
        List<Book> books;

        public Author(
                String id,
                String name,
                List<Book> books
        ) {
            this.id = id;
            this.name = name;
            this.books = books;
        }
    }

    public static List<Tag> getTagsOfAuthorsBooks(
            List<Author> authors,
            List<String> searchAuthorIds
    ) {
        // код тут
    }
}

Спойлеры к решению

Подсказки
💡 Преобразуй идентификаторы авторов в Set для быстрого поиска.
💡 Сначала отфильтруй авторов по полю id.
💡 С помощью flatMap() разверни список авторов в поток книг.
💡 Затем вторым flatMap() получи теги всех книг.
💡 Обработай возможные значения null.

Решение
public static List<Tag> getTagsOfAuthorsBooks(
        List<Author> authors,
        List<String> searchAuthorIds
) {
    if (authors == null || searchAuthorIds == null) {
        return List.of();
    }

    Set<String> authorIds = new HashSet<>(searchAuthorIds);

    return authors.stream()
            .filter(Objects::nonNull)
            .filter(author -> authorIds.contains(author.id))
            .filter(author -> author.books != null)
            .flatMap(author -> author.books.stream())
            .filter(Objects::nonNull)
            .filter(book -> book.tags != null)
            .flatMap(book -> book.tags.stream())
            .filter(Objects::nonNull)
            .toList();
}

Сначала выбираются авторы с подходящими идентификаторами, затем вложенные коллекции последовательно разворачиваются:

авторы → книги → теги

Преобразование идентификаторов в HashSet позволяет проверять наличие идентификатора в среднем за O(1).

Повторяющиеся теги сохраняются. Если нужно вернуть только уникальные теги, необходимо определить правило их сравнения и добавить distinct().