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

将映射(A-B列表)反向到(B-A列表)

彭存
2023-03-14

我编写了这个函数,它看起来很有用,但我想知道是否有更干净的解决方案。

    public static <K, V> Map<V, List<K>> reverseMap(Map<K, List<V>> map) {
        return map.entrySet().stream()
                .flatMap(entry -> entry.getValue().stream().map(value -> new AbstractMap.SimpleEntry<>(value, entry.getKey())))
                .collect(Collectors.groupingBy(
                        AbstractMap.SimpleEntry::getKey,
                        Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList())));

    }

奖励问题:我有一个java 8约束,但是后来的版本如何改进它?我想我不再需要使用 AbstractMap.SimpleEntry,因为 Java 9 引入了 Map.entry(k, v) 函数。

共有1个答案

通啸
2023-03-14

由于您的问题中没有必要使用流,我将主张使用非流解决方案:

//example input
Map<Integer, List<Integer>> map = new HashMap<>();
map.put(1, Arrays.asList(11, 12, 13, 4));
map.put(2, Arrays.asList(21, 22, 23, 4));
map.put(3, Arrays.asList(31, 32, 33, 4));
//reversing
Map<Integer, List<Integer>> reversed = new HashMap<>();
map.forEach((key, list) -> {
    list.forEach(value -> {
        reversed.computeIfAbsent(value, k -> new ArrayList<>()).add(key);
    });
});
//end result:
//{32=[3], 33=[3], 4=[1, 2, 3], 21=[2], 22=[2], 23=[2], 11=[1], 12=[1], 13=[1], 31=[3]}

在基于流的解决方案中,您将在映射中为每个键(列表值)对创建新的 Entry 对象,然后在重新组合到映射中时,这些对象必须创建其他条目。通过使用直接方法,可以避免创建这种多余的对象,并直接创建所需的条目。

请注意,并非所有内容都必须是流,“旧”的处理方式仍然是正确的,即使(在可读性和性能方面)不如流实现。

 类似资料:
  • 问题内容: 这是我的第一个问题,我开始学习Python。之间有什么区别: 和 在下面的示例中编写时,它显示不同的结果。 和 问题答案: 在中,在将右侧的表达式赋给左侧之前对其求值。因此,它等效于: 在第二个示例中,运行时已更改的值。因此,结果是不同的。

  • 我尝试了一些代码在Java中交换两个整数,而不使用第三个变量,即使用XOR。 以下是我尝试的两个交换函数: 该代码产生的输出如下: 我很想知道,为什么会有这样的说法: 和这个不一样?

  • 问题内容: 我尝试了一些代码,使用XOR在Java中交换两个整数而不使用第三个变量。 这是我尝试的两个交换函数: 这段代码产生的输出是这样的: 我很好奇,为什么这样说: 与这个不同吗? 问题答案: 问题是评估的顺序: 参见JLS第15.26.2节 首先,对左操作数求值以产生一个变量。 如果该评估突然完成,则赋值表达式由于相同的原因而突然完成;右边的操作数不会被评估,并且不会发生赋值。 否则,将保存

  • 问题内容: 今天,我发现了python语言一个有趣的“功能”,这让我感到非常悲伤。 那个怎么样?我以为两者是等同的!更糟糕的是,这是我调试时遇到的麻烦的代码 WTF!我的代码中包含列表和字典,并且想知道我到底怎么把dict的键附加到列表上而又没有调用.keys()。事实证明,这就是方法。 我认为这两个陈述是等效的。即使忽略这一点,我也可以理解将字符串追加到列表的方式(因为字符串只是字符数组),但是

  • 问题内容: 这是我必须弄清楚怎么可能的代码。我有一个线索,但我不知道该怎么做。我认为这与负数和正数有关,也可能与变量修饰符有关。我是一个初学者,我到处都看过解决方案,但是找不到可用的东西。 问题是:您需要声明和初始化两个变量。如果条件必须为真。 代码: 感谢您抽出宝贵的时间。 问题答案: 这对于基本类型是不可能的。您可以使用带框的整数来实现: 在和比较将使用未装箱的值1,而将比较引用,并会成功,因

  • Generic animation of numbers Parameters anumberstartslave number Anumberendslave number bnumberstartmaster number (start time ingeneral case) Bnumberendmaster number (end time in generalcase) getfunct