如何将字符串转换为HashMap?

37

我有一个 Java 属性文件,其中有一个名为 ORDERKEY。因此,在像下面这样加载属性文件之后,我使用 getProperty() 方法检索该 KEYVALUE

String s = prop.getProperty("ORDER");
然后
s ="SALES:0,SALE_PRODUCTS:1,EXPENSES:2,EXPENSES_ITEMS:3";
我需要从上面的字符串创建HashMap。 "SALES,SALE_PRODUCTS,EXPENSES,EXPENSES_ITEMS" 应该是 HashMap 的“KEY”,而 “0,1,2,3” 应该是“KEY”的“VALUE”。
如果它是硬编码的,它看起来像下面这样:
Map<String, Integer> myMap  = new HashMap<String, Integer>();
myMap.put("SALES", 0);
myMap.put("SALE_PRODUCTS", 1);
myMap.put("EXPENSES", 2);
myMap.put("EXPENSES_ITEMS", 3);

2
如果这对于给定的字符串确实是硬编码的解决方案,请保留它... 如果不是,请告诉我们你到目前为止尝试了什么以及你的问题是什么。 - pgras
http://mattgemmell.com/2008/12/08/what-have-you-tried/ - Denys Séguret
@pgras,我已经编辑了我的帖子。我认为现在它不难理解了。 - Bishan
1
这个回答解决了你的问题吗?将表示键值对的字符串转换为Map - Volo Myhal
10个回答

71
你可以使用 Guava 的 Splitter.MapSplitter 来实现这一点: GuavaSplitter.MapSplitter
Map<String, String> properties = Splitter.on(",")
    .withKeyValueSeparator(":")
    .split(inputString);

1
请注意,此操作返回一个不可变列表。 - xilef
1
@xilef,这就是它最好的部分! - KARASZI István
它返回给我一组键值对,而我想要一个HashMap。 - Sankalp
@Sankalp 返回的是一个 Map 而不是键值对。 - KARASZI István

56
使用 String.split() 方法以逗号作为分隔符获取键值对列表。遍历键值对,再次使用冒号作为分隔符调用 split() 方法以获取每个键值对的键和值。
Map<String, Integer> myMap = new HashMap<String, Integer>();
String s = "SALES:0,SALE_PRODUCTS:1,EXPENSES:2,EXPENSES_ITEMS:3";
String[] pairs = s.split(",");
for (int i=0;i<pairs.length;i++) {
    String pair = pairs[i];
    String[] keyValue = pair.split(":");
    myMap.put(keyValue[0], Integer.valueOf(keyValue[1]));
}

7
使用 foreach 循环可以保存一行数据! :) - Ayoub
1
String.split() 方法的链接已损坏。 - inquisitive
@KumarAnkit,逗号作为硬分隔符是OP的假设或要求之一。本答案基于此构建,否则无法实现。 - Xavi López
1
如果您的任何键或值包含逗号怎么办? - jay rangras
使用ObjectMapper会比这个更好、更快吧? - Jet Ezra

30
一句话概括:
HashMap<String, Integer> map = (HashMap<String, Integer>) Arrays.asList(str.split(",")).stream().map(s -> s.split(":")).collect(Collectors.toMap(e -> e[0], e -> Integer.parseInt(e[1])));

细节:

1)将输入对拆分并将字符串数组转换为List<String>,以便使用Java 1.8中的java.lang.Collection.Stream API。

Arrays.asList(str.split(","))

2)将得到的字符串列表"key:value"映射为字符串数组,其中[0]作为键,[1]作为值

map(s -> s.split(":"))

3) 使用流 API 中的 collect 终端方法来改变。

collect(Collector<? super String, Object, Map<Object, Object>> collector)

4) 使用Collectors.toMap()静态方法,它需要两个函数来执行从输入类型到键和值类型的变换。

toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)

其中T表示输入类型,K表示键类型,U表示值类型。

5) 以下lambda将String变异为String键和String变异为Integer

toMap(e -> e[0], e -> Integer.parseInt(e[1]))



使用Java 8享受流和lambda风格。 不再需要循环!


2
我可能会被标记,但我必须说,天啊!我从未意识到Java如此强大。 - Neerkoli
18
这条"代码(一行)"将会让未来的维护者们感到恶梦。 - Sundararaj Govindasamy
如此简单明了!! - kaleemsagard

7

我建议使用com.fasterxml.jackson.databind.ObjectMapper(Maven仓库链接:https://mvnrepository.com/artifact/com.fasterxml.jackson.core)。

final ObjectMapper mapper = new ObjectMapper();
Map<String, Object> mapFromString = new HashMap<>();
try {
    mapFromString = mapper.readValue(theStringToParse, new TypeReference<Map<String, Object>>() {
        });
} catch (IOException e) {
    LOG.error("Exception launched while trying to parse String to Map.", e);
}

5

使用Java 8:

Map<String, String> headerMap = Arrays.stream(header.split(","))
                    .map(s -> s.split(":"))
                    .collect(Collectors.toMap(s -> s[0], s -> s[1]));

3
你可以使用json.org中的JSONObject类将你的HashMap转换为格式良好的JSON字符串。

示例:

Map<String,Object> map = new HashMap<>();
map.put("myNumber", 100);
map.put("myString", "String");

JSONObject json= new JSONObject(map);

String result= json.toString();

System.out.print(result);

结果:

{'myNumber':100, 'myString':'String'}

您也可以从中获取关键信息,例如:
System.out.print(json.get("myNumber"));

结果:

100

1
OP想要的是相反的:从String创建HashMap! - Harish

3

假设没有任何密钥包含','':'

Map<String, Integer> map = new HashMap<String, Integer>();
for(final String entry : s.split(",")) {
    final String[] parts = entry.split(":");
    assert(parts.length == 2) : "Invalid entry: " + entry;
    map.put(parts[0], new Integer(parts[1]));
}

当我们遇到 , 时,可以使用哪些选项? - KumarAnkit

2
使用StringTokenizer来解析字符串。
String s ="SALES:0,SALE_PRODUCTS:1,EXPENSES:2,EXPENSES_ITEMS:3";
    Map<String, Integer> lMap=new HashMap<String, Integer>();


    StringTokenizer st=new StringTokenizer(s, ",");
    while(st.hasMoreTokens())
    {
        String [] array=st.nextToken().split(":");
        lMap.put(array[0], Integer.valueOf(array[1]));
    }

1
你可以使用 split 来完成它:
 String[] elements = s.split(",");
 for(String s1: elements) {
     String[] keyValue = s1.split(":");
     myMap.put(keyValue[0], keyValue[1]);
 }

不过,我个人会选择基于番石榴的解决方案。 https://dev59.com/IGkv5IYBdhLWcg3wjxhl#10514513


0

尝试

 String s = "SALES:0,SALE_PRODUCTS:1,EXPENSES:2,EXPENSES_ITEMS:3";
    HashMap<String,Integer> hm =new HashMap<String,Integer>();
    for(String s1:s.split(",")){
       String[] s2 = s1.split(":");
        hm.put(s2[0], Integer.parseInt(s2[1]));
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接