简体   繁体   English

使用Java流将字符串列表转换为地图列表

[英]Convert a list of strings to a list of maps using Java streams

I have a list of strings in the following pattern 我有以下模式的字符串列表

String test ="name=john,age=28;name=paul,age=30;name=adam,age=50";
List<String> listOfStrings = Arrays.asList(test.split(";"));

I want to convert the above list of strings to a list of map of key value pairs (like shown below). 我想将上面的字符串列表转换为键值对映射列表(如下所示)。

[{name=john, age=28}, {name=paul, age=30}, {name=adam, age=50}]

Each entry in the above list a map with keys as name and age and values as their corresponding values. 上面的每个条目都列出了一个映射,其中键为名称和年龄,值为相应的值。

This is what I have done to achieve the result. 这是我为实现结果而做的事情。

listOfStrings.stream()
  .map(record -> Arrays.asList(record.split(",")).stream().map(field -> field.split("="))
  .collect(Collectors.toMap(keyValue -> keyValue[0].trim(), keyValue -> keyValue[1].trim())))
  .collect(Collectors.toList());

I would like to know if that is efficient or if there is a better way to do it using Java streams. 我想知道这是否有效,或者是否有使用Java流的更好方法。

Here is another alternative using pattern matching, not as fast as a for loop but much faster than the original stream solution in my measurements. 这是使用模式匹配的另一种方法,速度不如for循环,但比我的测量中的原始流解决方案快得多。

public static void main(String[] args) {
    String test ="name=john,age=28;name=paul,age=30;name=adam,age=50";
    String patternString = "(name)=(\\w*),(age)=(\\d*)[;]?";
    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher(test);
    List<Map<String, String>> list = new ArrayList<>();

    while (matcher.find()) {
        Map<String, String> map = new HashMap<>();
        map.put(matcher.group(1), matcher.group(2));
        map.put(matcher.group(3), matcher.group(4));
        list.add(map);
    }
}

A slight performance improvement could be had by not matching against the keys (name & age) and instead hardcoding them when creating the map elements. 通过不与键(名称和年龄)匹配,而是在创建地图元素时对它们进行硬编码,可以稍微改善性能。

If you are out for performace, ditch the Stream API. 如果您想提高性能,请放弃Stream API。 Especially streams with substreams are really bad for writing highly performant applications. 尤其是带有子流的流确实不利于编写高性能的应用程序。

Here is a comparison of your Stream API version vs. a plain old for-loop: 这是您的Stream API版本与普通的for循环的比较:

public static void main(String[] args) {
  final String test = "name=john,age=28;name=paul,age=30;name=adam,age=50";

  final List<Map<String, String>> result1 = loop(test);
  final List<Map<String, String>> result2 = stream(test);

  System.out.println(result1);
  System.out.println(result2);
}


private static List<Map<String, String>> loop(String str) {
  long start = System.nanoTime();

  List<Map<String, String>> result = new ArrayList<>();
  String[] persons = str.split(";");

  for (String person : persons) {
    String[] attributes = person.split(",");
    Map<String, String> attributeMapping = new HashMap<>();

    for (String attribute : attributes) {
      String[] attributeParts = attribute.split("=");

      attributeMapping.put(attributeParts[0], attributeParts[1]);
    }

    result.add(attributeMapping);
  }

  long end = System.nanoTime();
  System.out.printf("%d nano seconds\n", (end - start));

  return result;
}

private static List<Map<String, String>> stream(final String str) {
  long start = System.nanoTime();

  List<String> listOfStrings = Arrays.asList(str.split(";"));
  List<Map<String, String>> result = listOfStrings.stream()
    .map(record -> Arrays.asList(record.split(",")).stream().map(field -> field.split("="))
    .collect(Collectors.toMap(keyValue -> keyValue[0].trim(), keyValue -> keyValue[1].trim())))
    .collect(Collectors.toList());

  long end = System.nanoTime();

  System.out.printf("%d nano seconds\n", (end - start));

  return result;
}

Outpout: Outpout:

183887 nano seconds 183887纳秒

53722108 nano seconds 53722108纳秒

[{name=john, age=28}, {name=paul, age=30}, {name=adam, age=50}] [{name = john,age = 28},{name = paul,age = 30},{name = adam,age = 50}]

[{name=john, age=28}, {name=paul, age=30}, {name=adam, age=50}] [{name = john,age = 28},{name = paul,age = 30},{name = adam,age = 50}]

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

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