如何解析字符串键/值并从中创建一个新的键/值并将其加载到同一个映射中?

时间:2016-02-05 22:43:42

标签: java dictionary

我有一个字符串和字符串的映射,其中我有键/值对,如下所示。对于每个client_123,我将有两个键,其值如下所示。

test_client_123=7|0.1|0.2|0.3|0.3
test_abc_pqr_client_123=16|5.5562501|5.1999998|13.6000004|13.6000004

test_client_987=9|0.3|0.4|0.7|0.7
test_abc_pqr_client_987=10|2.222|3.333|4.567|7.876  

这只是一个例子,我将以相同的格式拥有更多的键/值对。唯一的区别是client_123将是其他客户端,例如client_543=之后的数字也可能与管道不同。这就是全部。

每个值在管道分隔格式中的含义是什么:这里7是计数,0.1是ms的平均值,0.2是ms的中位数,0.3是ms的第95百分位数,0.3是ms的第99百分位数。同样对于第二行也是如此。并且它将始终采用这种格式。

问题陈述:

对于这一行test_client_123=7|0.1|0.2|0.3|0.3,我需要在下面创建新的键/值对并将其加载到相同的地图中:

test_in_process_client_123_count=7
test_in_process_client_123_avg_in_ms=0.1
test_in_process_client_123_median_in_ms=0.2
test_in_process_client_123_95_in_ms=0.3
test_in_process_client_123_99_in_ms=0.3

同样对于这一行test_abc_pqr_client_123=16|5.5562501|5.1999998|13.6000004|13.6000004,我想在下面创建新的键/值对并将其加载到相同的地图中:

test_abc_pqr_client_123_count=16
test_abc_pqr_client_123_avg_in_ms=5.5562501
test_abc_pqr_client_123_median_in_ms=5.1999998
test_abc_pqr_client_123_95_in_ms=13.6000004
test_abc_pqr_client_123_99_in_ms=13.6000004

我怎样才能做到这一点?下面是我在地图中加载所有原始键/值对的代码:

String response = restTemplate.getForObject(url, String.class);
Matcher m = PATTERN.matcher(response);
while (m.find()) {
    metricHolder.put(m.group(1), m.group(2));
}

现在,此metricHolder地图将具有高于原始键和管道分隔值的值。现在,我想在同一metricHolder地图中加载新的键/值对,并在将它们转换为新的键/值对后,也从地图中删除原始键/值对。

2 个答案:

答案 0 :(得分:1)

有趣的问题需要解决,我为此提出了自己的解决方案,希望它可以帮助您或者它对您正在尝试做的事情有用,如果我理解您想要在地图中添加新记录,基于以前的条目,那就是我做的:

public class DictionaryProcessor {

//Suffixes and common String parts
final static String PROCESS = "_in_process_";
final static String COUNT = "_count";
final static String AVG_IN_MS = "_avg_in_ms";
final static String MEDIAN_IN_MS = "_median_in_ms";
final static String N95_IN_MS = "_95_in_ms";
final static String N99_IN_MS = "_99_in_ms";
final static String PQR = "_pqr_";

public static void main(String[] args) {
    //Assuming this is the data you have:
    Map<String, String> dictionaryMap = new HashMap<String, String>();
    dictionaryMap.put("test_client_123", "7|0.1|0.2|0.3|0.3");
    dictionaryMap.put("test_abc_pqr_client_123", "16|5.5562501|5.1999998|13.6000004|13.6000004");
    dictionaryMap.put("test_client_987", "9|0.3|0.4|0.7|0.7");
    dictionaryMap.put("test_abc_pqr_client_987", "10|2.222|3.333|4.567|7.876");

    //I will define a temporary map to hold the new values
    Map<String, String> tempMap = new HashMap<String, String>();

    //We will iterate our map 
    for (Map.Entry<String, String> entry : dictionaryMap.entrySet()) {

        String currentKey = entry.getKey();//Get the current key
        String currentValue = entry.getValue();//Get the current value for the key
        //Since the value has the data separated by "|", I'd like to use "StringTokenizer" (Split or regex are worth to use to)
        StringTokenizer tokenizer = new StringTokenizer(currentValue, "|");

        String count = tokenizer.nextToken().trim();
        String avgData = tokenizer.nextToken().trim();
        String medianData = tokenizer.nextToken().trim();
        String n95data = tokenizer.nextToken().trim();
        String n99data = tokenizer.nextToken().trim();

        tempMap.put(generateNewKey(currentKey, currentKey.contains(PQR), COUNT), count);
        tempMap.put(generateNewKey(currentKey, currentKey.contains(PQR), AVG_IN_MS), avgData);
        tempMap.put(generateNewKey(currentKey, currentKey.contains(PQR), MEDIAN_IN_MS), medianData);
        tempMap.put(generateNewKey(currentKey, currentKey.contains(PQR), N95_IN_MS), n95data);
        tempMap.put(generateNewKey(currentKey, currentKey.contains(PQR), N99_IN_MS), n99data);
    }

    //Iterate the temporary map and add it to the existing dictionary map
    for (Map.Entry<String, String> entry : tempMap.entrySet()) {
        dictionaryMap.put(entry.getKey(), entry.getValue());
    }

    printMap(dictionaryMap);

}

private static void printMap(Map<String, String> targetMap) {
    for (Map.Entry<String, String> entry : targetMap.entrySet()) {
        System.out.println(entry.getKey() + "=" + entry.getValue());
    }
}

private static String generateNewKey(String currentKey, boolean hasPQR,
        String constant) {
    StringBuilder newKey = new StringBuilder();

    if (hasPQR) {
        newKey.append(currentKey).append(constant);
    } else {
        String firstPart = currentKey.substring(0, currentKey.indexOf("_"));
        String secondPart = currentKey.substring(currentKey.lastIndexOf("_") + 1, currentKey.length());
        newKey.append(firstPart).append(PROCESS).append(secondPart).append(constant);
    }

    return newKey.toString();
}

}

希望它有用。快乐的编码:)

答案 1 :(得分:0)

如果我已正确理解您的问题,您必须使用&#34; |&#34;解析当前地图中的值条目。 (管道)作为分隔符,然后将每个单独解析的值作为键值对放回。有点像下面的代码:

  String test_client_123="7|0.1|0.2|0.3|0.3" ;
  Map<String, String> the_map = new HashMap<String, String>() ;

  the_map.clear() ;
  String[] values = test_client_123.split("\\|");
  for (int i = 0; i < values.length; i++) {
      if (i == 0)
         the_map.put("count", values[i]);
      else if (i == 1)
         the_map.put("avg_in_ms", values[i]);
      else if (i == 2)
         the_map.put("med_in_ms", values[i]);
      else if (i == 3)
         the_map.put("95_in_ms", values[i]);
      else if (i == 4)
         the_map.put("99_in_ms", values[i]);
  }

希望它有所帮助...