Java 8 : Iterate and group objects from list based on object attributes

标签 java java-8 java-stream

我有一个类似于下面的列表(GlobalBooks)

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        GlobalBooks globalBooks = new GlobalBooks();

        List<Book> bookList  = new ArrayList<Book>();


        Book book = new Book();
        List<BookContent> bookContents = new ArrayList<BookContent>();

        book.setBookName("A");
        BookContent content = new BookContent();
        content.setDescription("December 2016");
        content.setComponentID(20l);
        bookContents.add(content);

        content = new BookContent();
        content.setDescription("January 2016");
        content.setComponentID(30l);
        bookContents.add(content);

        content = new BookContent();
        content.setDescription("Febuary 2016");
        content.setComponentID(40l);
        bookContents.add(content);
        book.setContents(bookContents);

        bookList.add(book);


        book = new Book();
        bookContents = new ArrayList<BookContent>();

        book.setBookName("B");
        content = new BookContent();
        content.setDescription("December 2016");
        content.setComponentID(20l);
        bookContents.add(content);

        content = new BookContent();
        content.setDescription("January 2016");
        content.setComponentID(30l);
        bookContents.add(content);

        content = new BookContent();
        content.setDescription("Febuary 2016");
        content.setComponentID(40l);
        bookContents.add(content);
        book.setContents(bookContents);

        bookList.add(book);

        globalBooks.setBooks(bookList);


        System.out.println(globalBooks);


    }

}

我正在寻找可以流式传输 globalBooks 响应并根据 BooksContent 中的描述字段收集图书列表映射的 Java 8 函数。

Map<String,List<Books>>即所有具有相同描述的书籍都应该按描述分组在一起吗?

我可以通过常规 java 执行此操作,但代码变得太困惑和不整洁。

最佳答案

由于每本书都有不同描述的多个内容,因此您需要每本书出现在多个 map 条目中。所以我会使用 flatMap 为每个 BookContent 创建一个流元素,特别是 Description+Book 对。然后像往常一样使用 Collectors.groupingBy 收集到 map 中:

    Map<String,List<Book>> result = globalBooks.getBooks().stream().flatMap(
        (Book b) -> b.getContents().stream().map(
            (BookContent bc) -> new Pair<>(bc.getDescription(), b)
        )
    ).collect(Collectors.groupingBy(
        Pair::getKey,
        Collectors.mapping(Pair::getValue, Collectors.toList())
    ));

注意:

我上面使用的 Pair 类来自 javafx.util.Pair。但是,您可以轻松地使用 AbstractMap.SimpleEntry、您自己的 Pair 类或任何能够容纳两个对象的集合数据类型。

关于Java 8 : Iterate and group objects from list based on object attributes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42017314/

相关文章:

java - 错误: <identifier> expected

java - 在 Java 中为 2D 太空射击游戏创建游戏循环

java - 如何将 java 8 流收集/减少到 pojo 中?

java - 如何根据 Collection 值的大小对 Map 进行排序?

datetime - 如何在 Java 中将 ZoneId 转换为 DateTimeZone

java - 将 2 个集合转换为 Map

java - 正确验证同一天内的时间间隔

java - 如何使用 Substance LaF 获取按钮的文本颜色?

java - Java 7/8 泛型中嵌套通配符的可分配性差异

java - 将字符串转换为 java.util.Stream<Character>