简体   繁体   English

将表示键值对的字符串转换为 Map

[英]Convert string representing key-value pairs to Map

How can I convert a String into a Map:如何将字符串转换为地图:

Map m = convert("A=4 H=X PO=87"); // What's convert?
System.err.println(m.getClass().getSimpleName()+m);

Expected output:预期输出:

HashMap{A=4, H=X, PO=87}

There is no need to reinvent the wheel.没有必要重新发明轮子。 The Google Guava library provides the Splitter class . Google Guava 库提供了Splitter

Here's how you can use it along with some test code:以下是如何将它与一些测试代码一起使用:

package com.sandbox;

import com.google.common.base.Splitter;
import org.junit.Test;

import java.util.Map;

import static org.junit.Assert.assertEquals;

public class SandboxTest {

    @Test
    public void testQuestionInput() {
        Map<String, String> map = splitToMap("A=4 H=X PO=87");
        assertEquals("4", map.get("A"));
        assertEquals("X", map.get("H"));
        assertEquals("87", map.get("PO"));
    }

    private Map<String, String> splitToMap(String in) {
        return Splitter.on(" ").withKeyValueSeparator("=").split(in);
    }

}

Java 8 to the rescue! Java 8 来救援!

import static java.util.stream.Collectors.*;

Map<String, String> result = Arrays.stream(input.split(" "))
    .map(s -> s.split("="))
    .collect(Collectors.toMap(
        a -> a[0],  //key
        a -> a[1]   //value
    ));

NOTE: Assuming no duplicates.注意:假设没有重复。 Otherwise look into the 3rd 'mergeFunction' argument.否则请查看第三个“mergeFunction”参数。

You don't need a library to do that.你不需要图书馆来做到这一点。 You just need to use StringTokenizer or String.split and iterate over the tokens to fill the map.您只需要使用 StringTokenizer 或String.split并遍历令牌以填充地图。

The import of the library plus its settings would be almost as big as the three lines of code needed to do it yourself.库的导入及其设置几乎与自己完成所需的三行代码一样大。 For example :例如 :

public static Map<String, String> convert(String str) {
    String[] tokens = str.split(" |=");
    Map<String, String> map = new HashMap<>();
    for (int i=0; i<tokens.length-1; ) map.put(tokens[i++], tokens[i++]);
    return map;
}

Note that in real life, the validation of the tokens and the string, highly coupled with your business requirement, would probably be more important than the code you see here.请注意,在现实生活中,与您的业务需求高度相关的令牌和字符串的验证可能比您在此处看到的代码更重要。

public static Map<String, String> splitToMap(String source, String entriesSeparator, String keyValueSeparator) {
    Map<String, String> map = new HashMap<String, String>();
    String[] entries = source.split(entriesSeparator);
    for (String entry : entries) {
        if (!TextUtils.isEmpty(entry) && entry.contains(keyValueSeparator)) {
            String[] keyValue = entry.split(keyValueSeparator);
            map.put(keyValue[0], keyValue[1]);
        }
    }
    return map;
}

And now you can use it for different types of entries/key-values separators, just like this现在您可以将它用于不同类型的条目/键值分隔符,就像这样

Map<String, String> responseMap = splitToMap(response, " ", "=");

split String by " ", then split each item by "=" and put pairs into map.用“”分割字符串,然后用“=”分割每个项目并将成对放入地图。 Why would you need "library" for such elementary thing?为什么你需要“图书馆”来做这种基本的事情?

private HashMap<String, String> convert(String str) {
    String[] tokens = str.split("&");
    HashMap<String, String> map = new HashMap<String, String>();
    for(int i=0;i<tokens.length;i++)
    {
        String[] strings = tokens[i].split("=");
        if(strings.length==2)
         map.put(strings[0], strings[1].replaceAll("%2C", ","));
    }

    return map;
}

Let me propose another way for specific case when you have key-value pairs in different lines: to use Java's built-in Properties class:当您在不同行中有键值对时,让我针对特定情况提出另一种方法:使用 Java 的内置Properties类:

Properties props = new Properties();
props.load(new StringReader(s));

BENEFITS:好处:

  • short短的
  • for any Java version对于任何 Java 版本
  • gives you a ready-to-use Map<Object, Object> also supplying handy String props.getProperty(String) method为您提供现成的 Map<Object, Object> 还提供方便的String props.getProperty(String)方法
  • StringReader has built-in 8k buffer (you may adjust buffering on mega input) StringReader具有内置的 8k 缓冲区(您可以调整大型输入的缓冲)
  • steady against different newline characters对不同的换行符保持稳定
  • you may base on defaults Map with new Properties(defaultsMap)您可以基于默认映射和new Properties(defaultsMap)

WARNINGS (could be virtue or vice):警告(可能是美德或恶习):

  • has special parsing rules for '.properties' format (you may want to peek inside Properties class to learn more):对 '.properties' 格式有特殊的解析规则(您可能想查看Properties类以了解更多信息):
    • trims spaces/tabs from keys/values从键/值中修剪空格/制表符
    • has special-meaning characters:具有特殊含义的字符:
      • ! , # at beginning of line is comment , #行首是注释
      • = or : is key-value separator =:是键值分隔符
      • \\ is used as escape character for unicode/special chars. \\用作 unicode/特殊字符的转义字符。 For example, you may want to prepare your string with s = s.replace("\\\\", "\\\\\\\\");例如,您可能希望使用s = s.replace("\\\\", "\\\\\\\\");准备您的字符串s = s.replace("\\\\", "\\\\\\\\");
  • resulting Map is based on HashTable having synchronization unneeded in most cases结果 Map 基于HashTable ,在大多数情况下不需要同步
String elementType = StringUtility.substringBetween(elementValue.getElementType(), "{", "}");
Map<String, String>  eleTypeMap = new HashMap<String, String>();
StringTokenizer token = new StringTokenizer(elementType, ",");
while(token.hasMoreElements()){
    String str = token.nextToken();
    StringTokenizer furtherToken = new StringTokenizer(str,"=");
    while(furtherToken.hasMoreTokens()){
        eleTypeMap.put(furtherToken.nextToken(), furtherToken.nextToken());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM