有没有更好的方法来使用Java 8来填充LinkedHashMap?

Are*_*efe 4 java java-8

我有一些代码,它们分割一个字母串,用它制作一个List,Character然后Integer用字母和它的频率填充一个LinkedHashMap .代码如下,

   List<String> values = Arrays.asList((subjects.split(",")));
            for (String value : values) {
                char v = value.charAt(0);
                map.put(v, map.containsKey(v) ? map.get(v) + 1 : 1);
            }
            map.put('X', 0);
Run Code Online (Sandbox Code Playgroud)

如何用Java 8简洁地编写它?谢谢.

shm*_*sel 8

试试这个:

LinkedHashMap<Character, Long> counts = Pattern.compile(",")
        .splitAsStream(subjects)
        .collect(Collectors.groupingBy(
                s -> s.charAt(0),
                LinkedHashMap::new,
                Collectors.counting()));
Run Code Online (Sandbox Code Playgroud)

如果你必须有一个Integer计数,你可以像这样包装计数收集器:

Collectors.collectingAndThen(Collectors.counting(), Long::intValue)
Run Code Online (Sandbox Code Playgroud)

另一种选择(感谢@Holger):

Collectors.summingInt(x -> 1)
Run Code Online (Sandbox Code Playgroud)

作为旁注,您可以使用以下代码替换循环更新:

map.merge(v, 1, Integer::sum);
Run Code Online (Sandbox Code Playgroud)

  • @AmirPashazadeh`conjects.split(",")`对我说了很多. (2认同)
  • @Are:我怀疑,"使用整数会节省内存".在地图中,您有对象,而不是原始数据类型.虽然这些对象封装了原始值,但它们也受特定于JVM的开销和填充的影响,从而均衡了"Long"和"Integer"之间的大小差异.作为一个有趣的事实,在当前版本中,`Collectors.summingLong(x - > 1L)`(和分别为`Collectors.summingInt(x - > 1)`比`Collectors.counting()`更高效发生的事.但这将在下一个版本中发生变化. (2认同)