映射合并函数(不应该调用!?)

时间:2018-04-27 07:47:04

标签: java

我没有在下面发布这个相当简短的方法,为什么调用merger()函数(以确定与同一个键相关的值会发生什么)。

该方法应该按应用程序对搜索配置列表进行分组,并按地图键(应用程序名称)以及地图值(按名称搜索配置)对其进行排序。也许第二个流不是直接的,我可以/应该使用另一种方法,但是我想知道发生了什么。

输出就是这样的:

  • App1的
    • 搜索配置标题1
    • 搜索配置标题2
  • App2的
    • 搜索配置标题
  • App3的
    • 搜索配置标题1
    • 搜索配置标题2
    • 搜索配置标题3

ApplicationInfo实现不会覆盖int hashCode()也不会覆盖boolean equals(Object)

我原以为每个搜索配置列表的第二个流中的映射键总是不同的。但是,在一个特定的情况下,调用merge-function,我不知道它为什么被调用。

public SortedMap<ApplicationInfo, List<SearchConfigInfo>> groupByApplications(final BusinessLogicProcessingContext  ctx,
                                                                              final List<SearchConfigInfo>          searchConfigInfos) {
  requireNonNull(ctx, "The processing context must not be null.");
  requireNonNull(searchConfigInfos, "The search configuration informations must not be null.");

  final String                    lang;
  final RtInfoWithTitleComparator comp;

  lang = ContextLanguage.get(ctx);
  appComp = new RtInfoWithTitleComparator(lang);

  final Map<ApplicationInfo, List<SearchConfigInfo>> appToSearchConfigs;

  appToSearchConfigs = searchConfigInfos.stream()
                                        .collect(groupingBy(searchConfig -> RtCache.getApplication(searchConfig.getApplicationGuid())));

  return appToSearchConfigs.entrySet()
                           .stream()
                           .collect(toMap(Map.Entry::getKey,
                                          p_entry -> _sortValueList(p_entry.getValue()),
                                          merger(),
                                          () -> new TreeMap<>(appComp)));
}

地图的一般合同是:

“将键映射到值的对象。映射不能包含重复键;每个键最多可映射一个值。”

这就是为什么我真的很想知道在这种情况下会发生什么。

private static BinaryOperator<List<SearchConfigInfo>> merger() {
  return (list1, list2) -> { System.out.println(RtCache.getApplication(list1.get(0).getApplicationGuid()).hashCode());
        System.out.println(RtCache.getApplication(list2.get(0).getApplicationGuid()).hashCode());

         System.out.println(list1.get(0).getApplicationGuid().equals(list2.get(0).getApplicationGuid()));
    list1.addAll(list2);

    return list1;
  };
}

正如我在简单的STDOUT调试语句中看到的那样,hashCodes是不同的,并且它们彼此不相等。

1 个答案:

答案 0 :(得分:1)

请注意,作为TreeMap方法提供的供应商函数的结果,您提供了Collectors.toMap()

的最后一个参数):

toMap(Map.Entry::getKey,
       p_entry -> _sortValueList(p_entry.getValue()),
       merger(),
       () -> new TreeMap<>(appComp)));

(供应商函数提供收集器将用于包含结果的集合 - 因此在这种情况下,它始终提供TreeMap。)

A TreeMap performs key comparisons with compareTo(),这就是为什么在这种情况下可以获得密钥冲突的原因 - 相对于供应商地图而不是它们所源自的地图进行冲突。