【问题标题】:replace all keys in hashmap starting with a character替换 hashmap 中以字符开头的所有键
【发布时间】:2010-10-04 12:08:58
【问题描述】:
Set<String> tempSet = new HashSet<String>();
for (Map.Entry<String, String> entry : map.entrySet()) {
     String orginalKeys = entry.getKey();
     System.out.println(orginalKeys);
     String newKey = orginalKeys.replace('.','/');
     if (!newKey.equals(orginalKeys)) {
        map.put(newKey, entry.getValue());
        tempSet.add(orginalKeys);
        map.remove(orginalKeys);
     }
}
System.out.println(map);

这仅替换了一个键,但我想用上述事件替换所有键。我要做什么错了?

【问题讨论】:

  • 您的代码缺少右大括号。
  • @Reddy,不再是了,Andreas 已经修复了它。
  • @Colin - 这次他问为什么 他的 解决方案不起作用。这是一个后续问题,而不是重复的 IMO。
  • @Stephen C,我的错,我认为这是完全相同的问题。

标签: java


【解决方案1】:

我认为这段代码没有问题。假设您的地图有多个与标准匹配的键,例如包含至少一个点 (.),应该使用从 originalkeys 中获取的值创建多个新键,并且应该删除多个这些 originalkey。

另一种方法:只需创建一个新地图并删除旧地图:

Map<String, String> newMap = new HashMap<String, String>();
for (Map.Entry<String, String> entry : map.entrySet()) 
  newMap.put(entry.getKey().replace('.', '/'), entry.getValue());
map = newMap;

(如果你还需要那个tempSet,修改for循环里面的代码)

【讨论】:

  • 这会将所有键替换为点字符还是一个?
  • 它将为源映射中的每个键/值对创建一个新的键/值对,并且每个键的所有点都将替换为斜线。
【解决方案2】:

这仅替换了一个键,但我想用上述事件替换所有键。我做错了什么?

通常我希望您的代码提供ConcurrentModificationException。问题是您在迭代地图时正在修改地图。

javadoc for HashMap 是这样说的:

“这个类的所有“集合视图方法”返回的迭代器都是快速失败的:如果在创建迭代器后的任何时间对映射进行结构修改,除了通过迭代器自己的删除方法之外的任何方式,迭代器将抛出ConcurrentModificationException。因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。”

“请注意,不能保证迭代器的快速失败行为,因为一般来说,在存在不同步的并发修改的情况下不可能做出任何硬保证。快速失败迭代器抛出ConcurrentModificationException 最好-工作量基础。因此,编写一个依赖此异常的正确性的程序是错误的:迭代器的快速失败行为应仅用于检测错误。"

如果您在your previous question 的答案中同时查看我的解决方案和@Colin Herbert 的解决方案,您会发现我们在单独的数据结构中仔细记录了需要更改的内容。只有当迭代完成时,我们才会对原始 Map 进行更改。这很关键。没有它,解决方案就行不通。

【讨论】:

    【解决方案3】:

    理想情况下,此代码应该在您迭代 map.entrySet()) 并同时更新 map.put(newKey, entry.getValue()) 时抛出 java.util.ConcurrentModificationException;

    如前所述,您可以创建一个新的临时地图并替换为原始地图

    或 您可以获取列表中的键并迭代列表

    String[] keyArray = map.keySet().toArray(new String[map.size()]);
        Set<String> tempSet = new HashSet<String>();
        for (String orginalKeys : keyArray) {
            System.out.println(orginalKeys);
            String newKey = orginalKeys.replace('.', '/');
            if (!newKey.equals(orginalKeys)) {
                map.put(newKey, map.get(orginalKeys));
                tempSet.add(orginalKeys);
                map.remove(orginalKeys);
            }
        }
        System.out.println(map);
    

    【讨论】:

      【解决方案4】:

      我不确定您是否可以在迭代地图时对其进行修改。尝试先在列表中收集要更改的条目,然后再循环遍历该列表以进行更改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-13
        • 2011-04-20
        • 2015-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-07
        • 1970-01-01
        相关资源
        最近更新 更多