当前位置: 首页 > 知识库问答 >
问题:

如何在Collectors.to地图合并功能中获取密钥?

赵才俊
2023-03-14

收集器中发现重复的密钥条目时。toMap(),调用合并函数(o1,o2)

问题:如何获取导致复制的密钥?

String keyvalp = "test=one\ntest2=two\ntest2=three";

Pattern.compile("\n")
    .splitAsStream(keyval)
    .map(entry -> entry.split("="))
    .collect(Collectors.toMap(
        split -> split[0],
        split -> split[1],
        (o1, o2) -> {
            //TODO how to access the key that caused the duplicate? o1 and o2 are the values only
            //split[0]; //which is the key, cannot be accessed here
        },
    HashMap::new));

在合并函数中,我想根据键来决定是否取消映射,或者继续并接受这些值。

共有3个答案

闽高峯
2023-03-14

当然,还有一个简单而琐碎的技巧——将密钥保存在“密钥映射器”函数中,并在“合并”函数中获取密钥。因此,代码可能如下所示(假设键是整数):

final AtomicInteger key = new AtomicInteger(); 
...collect( Collectors.toMap( 
   item -> { key.set(item.getKey()); return item.getKey(); }, // key mapper 
   item -> ..., // value mapper
   (v1, v2) -> { log(key.get(), v1, v2); return v1; } // merge function
);

注意:这不利于并行处理。

郎魁
2023-03-14

当您忽略合并函数时,合并函数没有机会获得密钥,这与内置函数有相同的问题。

解决方案是使用不同的toMap实现,它不依赖于Map。合并

public static <T, K, V> Collector<T, ?, Map<K,V>>
    toMap(Function<? super T, ? extends K> keyMapper,
          Function<? super T, ? extends V> valueMapper) {
    return Collector.of(HashMap::new,
        (m, t) -> {
            K k = keyMapper.apply(t);
            V v = Objects.requireNonNull(valueMapper.apply(t));
            if(m.putIfAbsent(k, v) != null) throw duplicateKey(k, m.get(k), v);
        },
        (m1, m2) -> {
            m2.forEach((k,v) -> {
                if(m1.putIfAbsent(k, v)!=null) throw duplicateKey(k, m1.get(k), v);
            });
            return m1;
        });
}
private static IllegalStateException duplicateKey(Object k, Object v1, Object v2) {
    return new IllegalStateException("Duplicate key "+k+" (values "+v1+" and "+v2+')');
}

(这基本上就是Java

因此,在代码中只需重定向toMap调用并省略merge函数:

String keyvalp = "test=one\ntest2=two\ntest2=three";

Map<String, String> map = Pattern.compile("\n")
        .splitAsStream(keyvalp)
        .map(entry -> entry.split("="))
        .collect(toMap(split -> split[0], split -> split[1]));

(或ContainingClass.toMap如果它既不在同一个类中,也不在静态导入中)

收集器支持与原始toMap收集器类似的并行处理,尽管它不太可能从这里的并行处理中获益,即使有更多的元素要处理。

如果,如果我理解正确,您只想在基于实际键的合并函数中选择较旧或较新的值,您可以使用键谓词这样做

public static <T, K, V> Collector<T, ?, Map<K,V>>
    toMap(Function<? super T, ? extends K> keyMapper,
          Function<? super T, ? extends V> valueMapper,
          Predicate<? super K> useOlder) {
    return Collector.of(HashMap::new,
        (m, t) -> {
            K k = keyMapper.apply(t);
            m.merge(k, valueMapper.apply(t), (a,b) -> useOlder.test(k)? a: b);
        },
        (m1, m2) -> {
            m2.forEach((k,v) -> m1.merge(k, v, (a,b) -> useOlder.test(k)? a: b));
            return m1;
        });
}
Map<String, String> map = Pattern.compile("\n")
        .splitAsStream(keyvalp)
        .map(entry -> entry.split("="))
        .collect(toMap(split -> split[0], split -> split[1], key -> condition));

有几种方法可以自定义此收集器…

夏侯弘光
2023-03-14

您需要使用自定义收集器或使用不同的方法。

Map<String, String> map = new Hashmap<>();
Pattern.compile("\n")
    .splitAsStream(keyval)
    .map(entry -> entry.split("="))
    .forEach(arr -> map.merge(arr[0], arr[1], (o1, o2) -> /* use arr[0]));

编写一个自定义收集器是相当复杂的。你需要一个三消费者(键和两个值)是相似的,这不是在JDK中,这就是为什么我很确定没有内置函数使用。;)

 类似资料:
  • 使用for函数时,可以保存对象的位置,如(示例): 但是我不知道我怎么能得到这个位置,我怎么能知道它是否是最后一个使用地图功能的 有人能帮忙吗?

  • 我在数据帧中有两个映射类型列。有没有一种方法可以通过使用.withColumn在spark Sql中合并这两个列来创建新的映射列?

  • 在Go中,有没有更简单/更好的方法从地图中获取一部分密钥? 目前,我正在遍历地图并将关键点复制到一个切片:

  • 本文向大家介绍iOS实现图片存在本地、再从本地获取图片的功能,包括了iOS实现图片存在本地、再从本地获取图片的功能的使用技巧和注意事项,需要的朋友参考一下 iOS实现图片存在本地、再从本地获取图片的功能,代码如下: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!

  • 问题内容: 问题 从地图中获取数据 资料格式 注意 如何从上述结果中获得以下值 1.Event_dtmReleaseDate 2.strID 3.Trans_strGuestList 我试过的 res.Map(“ Event_dtmReleaseDate”); 错误:res.Map未定义(类型map [string] interface {}没有字段或方法Map) res.Event_dtmRel

  • 图形渲染 渲染系统,包括材质,光照,粒子等 UI系统 UI系统,包括与UI 相关的全部内容 动画系统 基于动画帧数据及骨骼顶点数据的通用动画及骨骼动画体系 音频 控制声音片段的播放暂停等 物理模拟 物理仿真模拟,主要包括刚体和碰撞等 脚本指南及事件系统 用于实现用户定义行为的脚本使用指南,包括事件的触发机制等 组件 用于为游戏对象添加不同功能的组件说明 资源 引擎使用到的各种不同资源介绍及整体资源