【问题标题】:Replace all the same values in a hash map at once一次替换哈希图中的所有相同值
【发布时间】:2020-08-30 16:02:08
【问题描述】:

假设我有一个看起来像这样的 HashMap:

1 -> A

2 -> B

3 -> B

4 -> A

5 -> A

6 -> B

其中 1、2、3、4、5、6 是键,A、B、C 是值。

我想要做的是在一个步骤中将 B 的所有值替换为 HashMap 中的 A 值(无需遍历元素 2、3 和 6 并将 A 的值放入每个一)。

基本上,我想删除对象 B 以及引用 B 的任何地方,用 A 替换它。我认为在 C/C++ 中,这可以使用指针来实现。我如何在 Java 中做到这一点?

【问题讨论】:

  • 你的意思是没有迭代,还是没有显式迭代?如果是后者,map.replaceAll((k, v) -> v.equals("B") ? "A" : v);.

标签: java object pointers reference hashmap


【解决方案1】:

你不能,这不是哈希图的作用或用途。

事实上,核心库中没有任何数据结构可以做到这一点。

一个简单的最佳途径是使用可变对象作为值。例如:

Map<Integer, StringBuilder> map = new HashMap<>();
StringBuilder a = new StringBuilder("A");
map.put(1, a);
map.put(2, a);
a.clear();
a.append("b");
System.out.println(map);

以上内容最终会打印“{1: b, 2: b}”。当然,如果您创建 2 个单独的 stringbuilder 对象,每个对象都包含文本“a”,则更改一个不会更改另一个。

Guava 具有双向映射,它们是双向的,但一般的想法是键和值都是唯一的,而您显然在这里没有。 Guava 也有 multimaps,将一个键映射成多个值;你也可以在这里使用这样的构造函数来处理一些东西:拥有一个由HashMap&lt;K, V&gt;Multimap&lt;V, K&gt; 组成的数据结构; hashmap 与上面一样,multimap 则相反,并且在您的示例中将B 映射到值236,然后您可以使用它来稍微有效地编写一个方法将完成“用 THAT 替换所有等于 THIS 的值”的工作,方法是在多映射中查找需要替换的键,然后替换映射中的那些 k/v 对,以及更新多映射。

请注意,这仍然是多个步骤,是 O(n),其中 n 是匹配键的数量,并且如果没有围绕您的大多数 API 的相当繁重的便捷 synchronized() 锁,就无法以多线程安全的方式完成收藏。

【讨论】:

    【解决方案2】:

    为什么不只维护第二个带有要设置的字符串的 Map,以便您可以维护 2 -> B, 3 -> B, 6 -> B 和 B -> [2, 3, 6]。

    Map<String, Set<Integer>> letterToKeys = new HashMap<>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-21
      • 2011-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 2015-04-19
      相关资源
      最近更新 更多