Java 8:根据对象属性从列表中迭代和分组对象

use*_*887 2 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);


    }

}
Run Code Online (Sandbox Code Playgroud)

我正在寻找java 8函数,它们可以流式传输globalBooks响应,并根据BooksContent中的description字段收集Book of Book的地图.

Map<String,List<Books>> 即所有具有相同描述的书籍应按描述分组?

我可以通过常规java来做到这一点,但代码变得太杂乱和不整洁.

Pat*_*ker 6

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

    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())
    ));
Run Code Online (Sandbox Code Playgroud)

注意:

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