【问题标题】:Merge Two Lists based on a condition and push the result to a map using java 8根据条件合并两个列表并使用 java 8 将结果推送到地图
【发布时间】:2020-07-25 22:20:34
【问题描述】:

我有两个列表源和目标想要根据某些条件合并它们并将数据推送到 Hashmap。我尝试了下面的代码,但我无法成功。

public List<Persona> fetchCommonPersonas(List<User> sourceList,
                                             List<User> targetList) {
final Map<String, String> map = new HashMap<>();
       map = sourceList.stream()
                .filter(source -> targetList.stream().anyMatch(destination -> {
                    if(destination.getAge().equals(source.getAge())) {
                        map.put(source.getUserId(), destination.getUserId());
                    }
                }
                ));    
}

【问题讨论】:

    标签: java lambda


    【解决方案1】:

    这是一种方法:

    Map<String, String> map = 
        sourceList.stream()
                  .map(source -> targetList.stream()
                                           .filter(dest -> dest.getUserId().equals(source.getUserId()))
                                           .map(dest -> new SimpleEntry<>(source.getPersonaId(), dest.getPersonaId()))
                                           .firstFirst())
                  .filter(Optional::isPresent)
                  .map(Optional::get)
                  .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));   
    

    您为源列表的每个元素找到目标列表的对应元素,将这些元素映射到包含两个人员 ID 的 Map.Entry,并将所有条目收集到 Map

    【讨论】:

    • 我在 NPE 遇到错误。它正在尝试为值 HashMap.java 行号 1224 插入 null。
    • @Raju 这表明 getPersonaId 在某些情况下返回 null。你应该过滤掉这种情况。
    • 没有任何空值。当我进一步调试它时,对于合并函数(在 HashMap.java 中),甚至键都为空。
    【解决方案2】:

    您可以利用源列表的groupingBy 来查找第二阶段中的数据,然后collect 目标和源ID 对如下 -

    Map<Integer, List<String>> sourceGrouping = sourceList.stream()
            .collect(Collectors.groupingBy(User::getAge,
                    Collectors.mapping(User::getId, Collectors.toList())));
    
    Map<String, String> map = targetList.stream()
            .filter(u -> sourceGrouping.containsKey(u.getAge()))
            .flatMap(u -> sourceGrouping.get(u.getAge())
                    .stream().map(s -> new AbstractMap.SimpleEntry<>(s, u.getId())))
            .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, 
                    AbstractMap.SimpleEntry::getValue));
    

    【讨论】:

      【解决方案3】:

      在我从 Eran 获得输入后,这是最后一段代码

      Map<String, String> commonMap = sourceList.stream()
              .flatMap(source -> targetList.stream()
              .filter(target -> source.getUserId().equals(target.getUserId()))
              .map(target -> new AbstractMap.SimpleImmutableEntry<>(sourcePersona.getPersonaId(), targetPersona.getPersonaId())))
              .filter(immutableEntry -> (immutableEntry != null
                      && StringUtils.isNotBlank(immutableEntry.getKey()) && StringUtils.isNotBlank(immutableEntry.getValue())))
              .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-02
        • 2018-11-18
        • 1970-01-01
        • 2016-06-22
        • 1970-01-01
        • 1970-01-01
        • 2012-07-10
        相关资源
        最近更新 更多