我有一个像这样的字符串:
pet:cat::car:honda::location:Japan::food:sushi
Run Code Online (Sandbox Code Playgroud)
现在:指示键值对,同时::分离对.我想将键值对添加到地图中.
我可以使用以下方法实现:
Map<String, String> map = new HashMap<String, String>();
String test = "pet:cat::car:honda::location:Japan::food:sushi";
String[] test1 = test.split("::");
for (String s : test1) {
String[] t = s.split(":");
map.put(t[0], t[1]);
}
for (String s : map.keySet()) {
System.out.println(s + " is " + map.get(s));
}
Run Code Online (Sandbox Code Playgroud)
但是有一种有效的方法吗?
我觉得代码是低效的,因为我使用了2个String[]对象并且split两次调用了函数.此外,我正在使用t[0],如果没有值t[1],可能会抛出一个ArrayIndexOutOfBoundsException.
Tag*_*eev 15
使用Guava库它是一个单行:
String test = "pet:cat::car:honda::location:Japan::food:sushi";
Map<String, String> map = Splitter.on( "::" ).withKeyValueSeparator( ':' ).split( test );
System.out.println(map);
Run Code Online (Sandbox Code Playgroud)
输出:
{pet=cat, car=honda, location=Japan, food=sushi}
Run Code Online (Sandbox Code Playgroud)
这也可能比JDK更快,String.split因为它不会创建正则表达式"::".
更新它甚至可以正确处理评论中的角落案例:
String test = "pet:cat::car:honda::location:Japan::food:sushi:::cool";
Map<String, String> map = Splitter.on( "::" ).withKeyValueSeparator( ':' ).split( test );
System.out.println(map);
Run Code Online (Sandbox Code Playgroud)
输出是:
{pet=cat, car=honda, location=Japan, food=sushi, =cool}
Run Code Online (Sandbox Code Playgroud)
JB *_*zet 14
您可以使用以下代码单独调用split()和String上的单个传递.但它当然假设String首先是有效的:
Map<String, String> map = new HashMap<String, String>();
String test = "pet:cat::car:honda::location:Japan::food:sushi";
// split on ':' and on '::'
String[] parts = test.split("::?");
for (int i = 0; i < parts.length; i += 2) {
map.put(parts[i], parts[i + 1]);
}
for (String s : map.keySet()) {
System.out.println(s + " is " + map.get(s));
}
Run Code Online (Sandbox Code Playgroud)
以上可能比您的解决方案更有效,但是如果您发现代码更清晰,那么请保留它,因为这种优化几乎没有机会对性能产生重大影响,除非您这样做数百万次.无论如何,如果它如此重要,那么你应该测量和比较.
编辑:
对于那些想知道::?上述代码意味着什么的人:String.split()将正则表达式作为参数.分隔符是与正则表达式匹配的子字符串.::?是一个正则表达式,意思是:1个冒号,后跟0或1个冒号.因此它允许考虑::和:作为分隔符.