java8字符串replaceall已更改的行为

kkih6yb8  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(300)

我有这个 text = "$i $index" 这张Map:

Map<String, String> vars = new HashMap<String, String>();

        vars.put("i","index0");
        vars.put("index","counter0");

目标是用相对值替换所有键。
在这个测试中,replaceall方法中使用的正则表达式是连接的结果

firstTest();
            // first test results:
            // java 7: index0  counter0
            // java 8: index0  index0ndex

在这种情况下,replaceall方法中使用的正则表达式是一个完整的字符串

secondTest();
            // second test resuls:
            // java 7: index0  index0ndex
            // java 8: index0  index0ndex

最后,我将pattern.quote方法与串联的字符串和完整的相同字符串进行比较

thirdTest();
            // third test results:
            // java 7: first: \Q$index\E second: \Q$index\E are equals: true
            // java 8: first: \Q$index\E second: \Q$index\E are equals: true

第一个测试代码:

private static void firstTest() {
    Map<String, String> vars = new HashMap<String, String>();

    vars.put("i","index0");
    vars.put("index","counter0");

    String text = "$i  $index";

    for (Entry<String, String> var : vars.entrySet())
        text = text.replaceAll(Pattern.quote("$"+var.getKey()), var.getValue());

    System.out.println(text);
}

第二个测试代码:

private static void secondTest() {
    Map<String, String> vars = new HashMap<String, String>();

    vars.put("$i","index0");
    vars.put("$index","counter0");

    String text = "$i  $index";

    for (Entry<String, String> var : vars.entrySet())
        text = text.replaceAll(Pattern.quote(var.getKey()), var.getValue());

    System.out.println(text);
}

第三个测试代码:

private static void thirdTest() {
    Map<String, String> vars = new HashMap<String, String>();
    vars.put("index","counter0");

    String firstQuote = Pattern.quote("$"+vars.keySet().toArray()[0]);
    String secondQuote = Pattern.quote("$index");

    System.out.println("first: " + firstQuote + " second: " + secondQuote 
                     + " are equals: " + firstQuote.equals(secondQuote));

}

有人能解释为什么我得到如此不同的结果吗?

r7knjye2

r7knjye21#

输出的变化将是由于迭代的顺序。
在遍历变量时,如果 $i 首先在文本字符串中 $i 加上1美元 $index 被替换。在第二次迭代中,没有任何内容会被替换,因为它在字符串中没有找到任何“$index”。
如果你能调试你的代码,你就能找到答案。要以某种排序顺序获取值,请使用linkedhashmap(按插入顺序保存)或treemap、sortedmap(按您设计的自定义顺序)
java.util.hashmap无序;你不能也不应该再假设什么了。
这个类不保证Map的顺序;特别是,它不能保证随着时间的推移,订单将保持不变。
linkedhashmap使用插入顺序。
此实现与hashmap的不同之处在于,它维护一个贯穿其所有条目的双链接列表。这个链表定义了迭代顺序,通常是键插入到Map中的顺序(插入顺序)。
treemap是一个sortedmap,它使用自然或自定义的键顺序。
Map根据其键的自然顺序进行排序,或者由Map创建时提供的比较器进行排序,具体取决于所使用的构造函数。

相关问题