简体   繁体   English

使用字符查找HashMap中的所有键并替换它

[英]Finding all keys in a HashMap with a character an replace it

我有一个HashMap,现在我需要找到HashMap里面的所有键,里面有一个特殊的字母 ,并用另一个字母替换它

You could try this : 你可以试试这个:

public void replaceKeysChar(char originalChar, char newChar, Map<String, ?> map) {
    Map<String, Object> tempMap = new HashMap<String, Object>();
    for (Map.Entry<String, ?> entry : map.entrySet()) {
        String key = entry.getKey();
        if(key != null){
            key = key.replace(originalChar, newChar);
        }
        tempMap.put(key, entry.getValue());
    }
    map.clear();
    map.putAll(tempMap);
}

This way you handle only char, and you don't change the implementation. 这样您只处理char,并且您不会更改实现。 Plus when you iterate you don't add item in your map (it would be a bad idea). 另外,当您迭代时,不要在地图中添加项目(这不是一个坏主意)。

If you don't care about the implementation simply return the tempMap and remove the clear / putAll part (it will consume less resources). 如果您不关心实现,只需返回tempMap并删除clear / putAll部分(它将消耗更少的资源)。

EDIT : 编辑:

After @locka's answer I think I should specify that this method can't handle collisions. 在@ locka的回答之后我想我应该指定这个方法不能处理冲突。

If your Map contains the keys "toto" and "tata" and you do a `replaceKeysChar('a','o', map) only one of the values between "toto"'s value and "tata"'s value will be in the map, the other will simply be ignored. 如果你的Map包含“toto”和“tata”键并且你执行`replaceKeysChar('a','o',map),那么“toto”的值和“tata”值之间只有一个值在地图中,另一个将被忽略。

EDIT bis: 编辑之二:

To handle collisions with exceptions (à la @Stephen C) just replace the old for by this one : 要处理异常冲突(例如@Stephen C),只需用以下内容替换旧for

    for (Map.Entry<String, ?> entry : map.entrySet()) {
        String key = entry.getKey();
        if(key != null){
            key = key.replace(originalChar, newChar);
        }
        if(tempMap.containsKey(key))
            throw new CollisionException();
        tempMap.put(key, entry.getValue());
    }
  1. Construct a new hashmap 构造一个新的hashmap
  2. Copy all the (key,value) pairs from the old hashmap, except that you replace OLDCHAR with NEWCHAR in the keys 复制旧hashmap中的所有(键,值)对,除了用键中的NEWCHAR替换OLDCHAR
  3. Swap the hashmaps over. 交换哈希图。

Here's a solution that "deals with" collisions by throwing an exception. 这是一个通过抛出异常来“处理”冲突的解决方案。

public void replaceKeysChar(char originalChar, char newChar, Map<String, ?> map) {
    Map<String, Object> tempMap = new HashMap<String, Object>();
    Set<String> tempSet = new HashSet<String>();
    for (Map.Entry<String, ?> entry : map.entrySet()) {
        String originalKey = entry.getKey();
        String newKey = originalKey .replace(originalChar, newChar);
        if (!newKey.equals(originalKey)) {
            if (map.containsKey(newKey) || tempMap.containsKey(newKey)) {
                throw new CollisionException(newKey);
            }
            tempMap.put(newKey, entry.getValue());
            tempSet.add(originalKey());
        }
    }
    map.keySet().removeAll(tempSet);
    map.putAll(tempMap);
}

EDIT 编辑

Fixed bugs ... in previous versions. 修复了以前版本中的错误。

So you want to change the Key. 所以你想改变密钥。 If the Hashalgorithm isn't something strange you'll have to get all key-value pairs, delete them from the hashmap, change them and reinsert them. 如果Hashalgorithm不是奇怪的东西,你将不得不获取所有键值对,从hashmap中删除它们,更改它们并重新插入它们。 Or insert them in a new Hashmap. 或者将它们插入新的Hashmap中。

I think people are concerned that you can't change a String key in situ because of immutability and the String's hashcode being tied the value of the string. 我认为人们担心你不能因为不变性而原位更改String键,并且String的hashcode被绑定了字符串的值。 Adding / removing keys could potentially work but then you run the risk of collisions, where you end up replacing an existing string by accident. 添加/删除密钥可能会起作用,但是您可能会遇到冲突的风险,最终会意外地替换现有的字符串。

The most obvious way to solve this issue is to use a custom key, eg 解决此问题最明显的方法是使用自定义密钥,例如

public class MyKey {
  static private Random r = new Random();

  private String keyValue; 
  private final int hashCode = r.nextInt();

  @Override
  public int hashCode() {
    return hashCode;
  }

  public void setKeyValue(String keyValue) {
    this.keyValue = keyValue;
  }

  public String getKeyValue() {
    return keyValue;
  }
}

This key has a string key value which you can easily set / get and a hashCode which is just a random number. 这个键有一个你可以轻松设置/获取的字符串键值和一个只是随机数的hashCode。 Once you add this key to the hash map you can change the string in situ without adding or removing the key. 将此密钥添加到哈希映射后,您可以在不添加或删除密钥的情况下就地更改字符串。 All you need do is iterate the key set and perform any processing you like on the key, all without affecting the hashcode or running the risk of collisions or anything else. 您所需要做的就是迭代密钥集并在密钥上执行您喜欢的任何处理,所有这些都不会影响哈希码或冒险发生冲突或其他任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM