簡體   English   中英

Java 8:根據對象屬性從列表中迭代和分組對象

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

我有一個列表(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);


    }

}

我正在尋找java 8函數,它們可以流式傳輸globalBooks響應,並根據BooksContent中的description字段收集Book of Book的地圖。

Map<String,List<Books>>即所有具有相同描述的書籍應按描述分組?

我可以通過常規java來做到這一點,但代碼變得太雜亂和不整潔。

由於每本書都有多個內容和不同的描述,因此您需要將每本書出現在多個地圖條目中。 所以我會使用flatMap為每個BookContent創建一個流元素,特別是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())
    ));

注意:

我上面使用的Pair類來自javafx.util.Pair 但是,您可以輕松地使用AbstractMap.SimpleEntry ,您自己的Pair類或任何能夠容納兩個對象的集合數據類型。

另一個解決方案可能是

    Map<String,List<Book>> result = new HashMap<String, List<Book>>();

    globalBooks.getBooks().stream().forEach(book->{

        book.getContents().stream().forEach(bookContent->{

            result.computeIfAbsent(bookContent.getDescription(),(list)->new ArrayList<Book>()).add(book);
        });
    });

這將完成工作:

Map<String, List<String>> result = bookList.stream().flatMap(b -> b.getContents().stream())
    .collect(Collectors.toMap(str -> str, str -> bookList.stream()
    .filter(b -> b.getContents().contains(str))
    .collect(Collectors.toList()), (a, b) -> {a.addAll(b);return a;}));

如果要並行執行此操作,只需使用Collectors.toConcurrentMap替換收集Collectors.toConcurrentMap

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM