将字符串拆分为键值对

2022-09-02 12:01:01

我有一个这样的字符串:

pet:cat::car:honda::location:Japan::food:sushi

Now 指示键值对,同时分隔这些对。我想将键值对添加到映射中。:::

我可以使用以下方法实现此目的:

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));
}

但是有没有一种有效的方法来做到这一点呢?


我觉得代码效率低下,因为我使用了2个对象并调用了两次函数。另外,我正在使用,如果没有值,可能会抛出一个。String[]splitt[0]t[1]ArrayIndexOutOfBoundsException


答案 1

您可以使用以下代码对 split() 执行单个调用,并对 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));
    }

上述内容可能比您的解决方案更有效一些,但是如果您发现您的代码更清晰,请保留它,因为除非您这样做数百万次,否则这种优化对性能产生重大影响的可能性几乎为零。无论如何,如果它如此重要,那么你应该衡量和比较。

编辑:

对于那些想知道上面的代码中意味着什么的人:String.split()将正则表达式作为参数。分隔符是与正则表达式匹配的子字符串。 是一个正则表达式,表示:1 个冒号,后跟 0 或 1 个冒号。因此,它允许考虑和作为分隔符。::?::?:::


答案 2

使用番石榴库,它是一行:

String test = "pet:cat::car:honda::location:Japan::food:sushi";
Map<String, String> map = Splitter.on( "::" ).withKeyValueSeparator( ':' ).split( test );
System.out.println(map);

输出:

{pet=cat, car=honda, location=Japan, food=sushi}

这也可能比 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);

输出为:

{pet=cat, car=honda, location=Japan, food=sushi, =cool}