Java8 String replaceAll 改变了行为
Java8 String replaceAll changed behavior
我有这张 text = "$i $index"
和这张地图:
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方法中使用的regex是一个完整的字符串
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));
}
有人可以解释为什么我得到如此不同的结果吗?
输出的变化是由于迭代的顺序。
在遍历 vars 时如果你先得到 $i
然后在文本字符串中 $i
和 $index
中的 $i 都会被替换。在第二次迭代中,不会替换任何内容,因为它在字符串中没有找到任何“$index”。
如果你能调试你的代码,你就能找到答案。要按某种排序顺序获取值,请使用 LinkedHashMap(按插入顺序保存)或 TreeMap、sortedMap(您设计的自定义顺序)
java.util.HashMap 是无序的;你不能也不应该假设除此之外的任何事情。
此 class 不保证地图的顺序;特别是,它不保证顺序会随着时间的推移保持不变。
java.util.LinkedHashMap 使用插入顺序。
此实现与 HashMap 的不同之处在于它通过其所有条目维护一个双向链表 运行。此链表定义了迭代顺序,通常是将键插入映射的顺序(插入顺序)。
java.util.TreeMap,一个 SortedMap,使用键的自然或自定义排序。
映射根据其键的自然顺序进行排序,或者根据使用的构造函数在映射创建时提供的比较器进行排序。
我有这张 text = "$i $index"
和这张地图:
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方法中使用的regex是一个完整的字符串
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));
}
有人可以解释为什么我得到如此不同的结果吗?
输出的变化是由于迭代的顺序。
在遍历 vars 时如果你先得到 $i
然后在文本字符串中 $i
和 $index
中的 $i 都会被替换。在第二次迭代中,不会替换任何内容,因为它在字符串中没有找到任何“$index”。
如果你能调试你的代码,你就能找到答案。要按某种排序顺序获取值,请使用 LinkedHashMap(按插入顺序保存)或 TreeMap、sortedMap(您设计的自定义顺序)
java.util.HashMap 是无序的;你不能也不应该假设除此之外的任何事情。
此 class 不保证地图的顺序;特别是,它不保证顺序会随着时间的推移保持不变。
java.util.LinkedHashMap 使用插入顺序。
此实现与 HashMap 的不同之处在于它通过其所有条目维护一个双向链表 运行。此链表定义了迭代顺序,通常是将键插入映射的顺序(插入顺序)。
java.util.TreeMap,一个 SortedMap,使用键的自然或自定义排序。
映射根据其键的自然顺序进行排序,或者根据使用的构造函数在映射创建时提供的比较器进行排序。