簡體   English   中英

Java Stream Api INNER JOIN 兩個列表

[英]Java Stream Api INNER JOIN Two Lists

如何使用 Java Stream Api 替換此代碼?

for (Book book : Books.getAllBooks()) {
        for (SearchResult searchResult : searchResultList) {
          if (searchResult.getTableName().replace("attr_", "") .equals(book.getTableName())) {
            bookList.add(book);
          }
        }
      }
List<Book> bookList = Books.getAllBooks().stream()
            .filter(e -> searchResultList.stream()
                         .anyMatch(f -> e.getTableName().equals(f.getTableName().replace("attr_", ""))))
            .collect(Collectors.toList());

我來自 C# 並錯過了 Java 8 API 中的那個特性,所以我自己寫了一個。 使用streamjoin你可以寫

Stream<Book> books = 
 join(Books.getAllBooks().stream())
 .withKey(Book::getTableName)
 .on(searchResultList.stream())
 .withKey(SearchResult::getTableName)
 .combine((book, searchResult) -> book)
 .asStream()

完全是你所要求的,但如果你使用番石榴,這里有另一個技巧:

List<Book> bookList = new ArrayList<>(Books.getAllBooks());
Lists.transform(bookList, Book::getTableName)
        .retainAll(Lists.transform(searchResultList, r -> r.getTableName().replace("attr_", ""));

在我看來,您的示例是連接操作的一個特例,因為您的結果集不包含SearchResult任何列。 對於大多數像我一樣進入這個問題的人來說, Java Stream 的一般連接操作就是他們想要的。 這是我的解決方案:

  • step 1, flatMap 判斷結果是否應該為null
  • 步驟 2,通過 nonNull 過濾步驟 1 中的流

它工作正常,雖然它不是那么優雅,看起來你自己實現了一個連接操作——

偽代碼可能像:

//init the two list
List l1 = ...;
List l2 = ...;

//join operation
res = l1.stream().flatMap(
    _item1 -> l2.stream().map(_item2 -> (_item1.join_key == _item2.join_key)?
         ([take the needed columns in item1 and item2]) : null
    )
).filter(Object::nonNull);

暫無
暫無

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

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