【问题标题】:Search by field on different classes and different lists Java 8 Stream按字段搜索不同类和不同列表 Java 8 Stream
【发布时间】:2021-06-02 02:43:39
【问题描述】:

我有三个包含不同对象的不同列表。我需要遍历每个列表,比较一个字段,如果相同,则创建新对象。

ObjectA: firstName, id
ObjectB: email, id 
ObjectC: birthday, id
Model: firstName, email, birthday, id

我能否以某种方式使用流搜索通过 id 的对象列表并在输出上创建具有提及字段的模型列表?

我试过这个:

List<ObjectA> list1;
List<ObjectB> list2;
List<ObjectC> list3;
List<Model> output = list1.stream().flatMap(p -> list2.stream()
                                  .filter(t -> p.getId().equals(t.getId())).findFirst()
                                  .flatMap(t -> list3.stream()
                                  .filter(i -> t.getId().equals(i.getId())).findFirst()
.flatMap(i -> new Model(p, i, t)))) // Model has a constructor, that takes classes as values
.collect(Collectors.toList());

【问题讨论】:

    标签: java list lambda collections java-stream


    【解决方案1】:

    这不适用于流,流适合处理同质数据,但事实并非如此。

    第 1 步是将列表转换为地图,将 id 映射到相关对象。

    然后,有了 3 张地图,您就可以合并了。首先制作所有 ID 的超集,然后为每个 ID 收集数据并创建对象。

    类似:

    Map<String, String> as = list1.stream()
      .collect(Collectors.toMap(ObjectA::getId, ObjectA::getName));
    Map<String, String> bs = list2.stream()
      .collect(Collectors.toMap(ObjectB::getId, ObjectB::getEmail));
    Map<String, LocalDate> cs = list3.stream()
      .collect(Collectors.toMap(ObjectC::getId, ObjectC::getBirthDate));
    
    var allIds = new HashSet<String>();
    allIds.addAll(as.keySet());
    allIds.addAll(bs.keySet());
    allIds.addAll(cs.keySet());
    
    var objs = allIds.stream()
      .map(id -> new ModelObj(id,
         as.getOrDefault(id, "(NoName)"),
         bs.getOrDefault(id, "(NoEmail)"),
         cs.get(id)))
      .collect(Collectors.toList());
    

    【讨论】:

    • 但是如果每个类有两个以上的字段呢?地图将不再相关?
    • 您的问题是:“一个字段”。您现在已经移动了球门柱。如果您有多个字段,那么您将创建一个容器类来捕获此多字段状态并将其用作键。如果没有地图,您将针对每个条目重新扫描每个列表,从而导致性能灾难。
    • 感谢您的回答,@rzwitserloot。我需要通过一个字段(id)来比较对象,所以我可以连接来自不同列表的用户信息。我的错,我在每个类中只提到了两个字段,因为它们有多个字段,但我写了一个作为示例。
    • 我的代码完全符合您的要求。它通过一个字段(id)收集,然后将它们合并为一个对象。如果你不明白它的一部分,哪一部分,也许我可以澄清一下。
    猜你喜欢
    • 1970-01-01
    • 2021-03-27
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多