Hashmap 将相同的键 "m" 替换为 "mL" ,是否有办法修复它?

Hashmap replace the same key "m" as "mL" , is there anyway to fix it?

我有这个数学表达式:

String exp = "k+(mP/P+mL/L)";

然后我创建一个新的 HashMap 并放入与上述表达式完全相同的参数:

Map<String, Integer> mp = new HashMap<>();
mp.put("k", 1);
mp.put("mP", 2);
mp.put("P", 3);
mp.put("mL", 4);
mp.put("L", 5);

最后,我通过将表达式的参数替换为值继续对所有条目集进行乱码处理,然后打印结果:

for(Map.Entry<String,Integer> e: mp.entrySet()){

    exp = exp.replace(e.getKey(),e.getValue().toString());
}
System.out.println(exp);

上面的结果是:“1+(m3/3 +m5/5)”

*但我想要这个:“1+(2/3+4/5)”

有什么办法吗?

使用正则表达式 replaceAll with word-boundary \b.

exp = exp.replaceAll("\b" + e.getKey() + "\b", e.getValue().toString());

您还可以查看 脚本 API 或 java REPL.

问题是因为HashMap没有保持插入顺序。使用保持插入顺序的LinkedHashMap将解决问题。

Map<String, Integer> mp = new LinkedHashMap<>();

String.replace() 替换所有出现的子字符串,因此如果 PmP 之前被替换,可能会导致您所描述的问题。为避免这种情况,您可以使用没有常用字母的占位符构建表达式。例如:

String exp = "a+(b/c+d/e)";

您还可以按长度对键进行排序:


import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public static void main(String[] args) {
    String exp = "k+(mP/P+mL/L)";

    Map<String, Integer> mp = new HashMap<String, Integer>();
    mp.put("mP", 2);
    mp.put("mL", 4);
    mp.put("k", 1);
    mp.put("P", 3);
    mp.put("L", 5);

    String[] keys = new String[mp.keySet().size()];

    int i = 0;
    for (String k : mp.keySet()) {
        keys[i] = k;
        i++;
    }

    /* Sort array by string length (longest string at the beginning) */
    Arrays.sort(keys, (a, b) -> Integer.compare(b.length(), a.length()));

    for (String k : keys) {
        exp = exp.replace(k, mp.get(k).toString());
    }
    System.out.println(exp); // 1+(2/3+4/5)
}

示例代码。

mp.entrySet()
    .stream()
    .sorted(Comparator.comparingInt(entry -> entry.getKey().length() * -1))
    .forEach((entry) -> exp[0] = exp[0].replace(entry.getKey(),entry.getValue().toString())
);