java - 要映射的动态字符串列表
问题描述
有没有一种有效的方法可以将下面的列表转换为地图列表?我正在寻找使用 Java Streams 的优化解决方案。非常感谢您的帮助。
List<String>
:
[
"src/main/java/com/abc.java",
"68",
"src/main/java/com/def.java",
"21",
"src/main/java/com/ghi.java",
"4",
"9",
"58,3",
"61,0",
"src/main/java/com/jkl.java",
"3",
"12",
"src/main/java/com/mno.java",
"8,0",
"13",
"40,5",
"48,2",
"61,5"
]
List<Map<String, List<String>>>
:
[{
"src/main/java/com/abc.java": ["68"]
},
{
"src/main/java/com/def.java": ["21"]
},
{
"src/main/java/com/ghi.java": ["4", "9", "58", "59", "60"]
},
{
"src/main/java/com/jkl.java": ["3", "12"]
},
{
"src/main/java/com/mno.java": ["13", "40", "41", "42", "43", "44", "48", "49", "61", "62", "63", "64", "65"]
}
]
解决方案
在这种情况下,我强烈建议您不要使用java-stream,因为您依赖于前面的元素。
Map<String, List<String>> o = list.stream()
.reduce(
new TreeMap<String, List<String>>(),
(map,j) -> {
if (j.startsWith("src")) {
map.putIfAbsent(j, new ArrayList<>());
} else {
map.get(map.lastKey()).add(j);
}
return map;},
(i,j) -> i);
如您所见,该解决方案存在许多缺陷:非常笨拙,难以阅读并且违反了无副作用原则:
通常不鼓励对流操作的行为参数产生副作用,因为它们通常会导致无意中违反无状态要求以及其他线程安全隐患。
将其与更适合这种处理的传统的、基于程序的和基于 for 循环的解决方案进行比较:
final Map<String, List<String>> map = new HashMap<>();
String lastKey = null;
for (String item: list) {
if (item.startsWith("src")) {
map.putIfAbsent(item, new ArrayList<>());
lastKey = item;
} else {
map.get(lastKey).add(item);
}
}
您询问:
我正在寻找使用 Java Streams 的优化解决方案
我只能回答:首先考虑任何可行的解决方案,然后使其对其他开发人员可维护和可读。最后,考虑效率和性能。
推荐阅读
- excel - 循环浏览所有工作簿和所有工作表,格式化并复制到模板
- bitbucket - 如何使用 Bitbucket api 创建多个分支限制?
- apache2 - 发现任何剩余的 apache 日志
- presto - 如何从日期中获取 bigint?
- html - 如何使用空格减少空格:css 属性而不更改文本中的行高
标签
- asp.net-mvc - 如何使用 ASP.Net MVC 将对象值传输到模态类?
- cordova - Cordova Windows 应用程序未使用依赖项文件夹构建 appx
- vuetify.js - 如何自定义 Vuetify?
- c# - 使用 CsvHelper(或类似库)从变量中读取 CSV
- r - 定义因子数据的顺序