簡體   English   中英

具有多個對象列表的 Java8 流

[英]Java8 Stream with Multiple List of Objects

我有兩個列表,我想根據 Object1 和 Object2 的屬性在其中執行一些操作。

對象 1:

public class Object1 {
        private String prop1;
        private String prop2;
}

對象 2:

public class Object2 {
        private String prop1;
        private String prop2;
        private String prop3;
        private boolean prop4;
}

我想使用流而不是使用大方法。

假設我們有以下列表:

List<Object1> object1List = // List of Object1's
List<Object2> object2List = // List of Object2's

現在,我想比較兩個列表中的 prop1 和 prop2,如果它們相等,我想從 Object2 獲取 prop3 並基於 prop3 現在我想從 Object2 中查看 prop4 為 true 的所有元素,並確保所有元素都為 true 。

例子:

Object1:
prop1  |  prop2
test1     value1
test1     value2

Object2:
prop1 | prop2 | prop3 | prop4
test1   value1  some    true
test1   value2  some1   true
test2   value3  some    true

現在從上面的示例中,我想同時流式傳輸列表並比較列表,如果 prop1 和 prop2 相等,我想在“some”的情況下獲得 prop3 並使用 prop3 值獲得所有 prop4 值“true” some" 並查看 prop1 和 prop2 是否在 Object 的第一個列表中並將它們收集在一個集合中。 我可以用傳統的方式做到這一點,但流看起來更易讀,代碼行更少。 我只是在學習流,任何想法都值得贊賞!

由於我很無聊,無法弄清楚這個問題在問什么,這里有一個使用 Streams 實現此功能的示例。 這里的關鍵是根據適用於流的每個元素的 Predicate 過濾/(任何)匹配。

主程序

import java.util.*; import java.util.stream.*;
class Main
{
  public static void main(String[] args) 
  {
    List<Object1> l1 = new ArrayList<>();//referred to as "first list" in comments
    List<Object2> l2 = new ArrayList<>();//referred to as "second list" in comments
    l1.add(new Object1("test1","value1"));
    l1.add(new Object1("test1","value2"));
    l2.add(new Object2("test1", "value1", "some", true));
    l2.add(new Object2("test1", "value2", "some1", true));
    l2.add(new Object2("test2", "value3", "some", true));
    //This is the stream of objects2 in second list that matched both prop1 and prop2 for at least one object1 in first list
    Stream<Object2> matchingProp1andProp2 = l2.stream().filter(obj2 -> l1.stream().anyMatch(obj1 -> obj1.prop1().equals(obj2.prop1()) && obj1.prop2().equals(obj2.prop2())));
    matchingProp1andProp2.forEach(match -> {
      //get the ones in second list that have same prop3 as the match and prop4 being true
      Stream<Object2> matchingCriteria = l2.stream().filter(obj2 -> match.prop3().equals(obj2.prop3()) && obj2.prop4());
      System.out.println(matchingCriteria.collect(Collectors.toList()));
    });
  }
}

選項 1 - 如果您認為單獨閱讀每個條件更容易:

Set<Object2> result = l2.stream().filter(o -> o.getProp3().equals("some"))
                                 .filter(o -> l1.contains(new Object1(o.getProp1(), o.getProp2())))
                                 .filter(Object2::isProp4)
                                 .collect(Collectors.toSet());

選項 2 - 具有所有條件的一個過濾器:

result = l2.stream().filter(o -> o.getProp3().equals("some") && l1.contains(new Object1(o.getProp1(), o.getProp2())) && o.isProp4() ).collect(Collectors.toSet());

我假設您的 Object1 覆蓋了 equals 和 hasCode,因此您可以使用 contains。

如果不是這種情況,則有點復雜,因為您必須分別比較 prop1 和 prop2,而不是對象本身:

result = l2.stream().filter(o -> o.getProp3().equals("some") && o.isProp4())
                    .filter(o1 -> l1.stream().anyMatch(o2 -> o2.getProp1().equals(o1.getProp1()) && o2.getProp2().equals(o1.getProp2())))
                    .collect(Collectors.toSet());

暫無
暫無

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

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