我有2个问题似乎无法解决。第一个是我需要一种方法来进行动态嵌套分组,用户可以传入1-n个嵌套组。
第二个问题是我需要将结果展平,其中键是连续而不是嵌套。
我的示例输入如下所示:
List<Map<String, String>> fakeData = new LinkedList<>();
Map<String, String> data1 = new HashMap<>();
data1.put("ip","10.0.1.0");
data1.put("uid","root");
data1.put("group","admin");
fakeData.add(data1);
Map<String, String> data2 = new HashMap<>();
data2.put("ip","10.0.1.1");
data2.put("uid","tiger");
data2.put("group","user");
fakeData.add(data2);
Map<String, String> data3 = new HashMap<>();
data3.put("ip","10.0.1.1");
data3.put("uid","woods");
data3.put("group","user");
fakeData.add(data3);
最终结果有一系列地图键:
{
"10.0.1.1user": [
{
"uid": "tiger",
"ip": "10.0.1.1",
"group": "user"
},
{
"uid": "woods",
"ip": "10.0.1.1",
"group": "user"
}
],
"10.0.1.0admin": [
"uid": "root",
"ip": "10.0.1.0",
"group": "admin"
]
}
请注意,键是连贯的,而不是映射中的嵌套映射。
我正在尝试创建一个可以动态而没有运气的分组:
fakeData.stream()
.collect(groupingBy(map -> map.get("ip"),
groupingBy(map -> map.get("uuid"),
... nested "n" times)));
这是我正在尝试实现的界面:
public Map<String, List<Map<String, String>>> doGrouping(List<String> columns,
List<Map<String, String>> data);
答案 0 :(得分:5)
尝试以下方法:
public Map<String, List<Map<String, String>>> doGrouping(
List<String> columns,
List<Map<String, String>> data) {
return data.stream()
.collect(Collectors.groupingBy(
elem -> columns.stream()
.map(elem::get)
.collect(Collectors.joining())));
}
首先,我流式传输了data
,这是一张地图列表。我立即使用Collectors.groupingBy
将流收集到列表地图中,并使用为流的每个元素计算的密钥。
计算密钥是棘手的部分。为此,我流式传输了columns
的给定列表,并将这些列中的每一列转换为其对应的流元素值。我通过Stream.map
方法完成了这项工作,并将elem::map
作为映射函数。最后,我使用Collectors.joining
将这个内部流收集到一个字符串中,它以有效的方式将流的每个元素连接成一个最终的字符串。
修改:如果columns
的所有元素都作为data
中地图元素的键存在,则上述代码效果很好。为了更安全,请使用以下内容:
return data.stream()
.collect(Collectors.groupingBy(
elem -> columns.stream()
.map(elem::get)
.filter(Objects::nonNull)
.collect(Collectors.joining())));
此版本过滤掉流中的null
个元素,如果某个地图元素不包含columns
列表中指定的密钥,则可能会出现这种情况。
答案 1 :(得分:1)
不确定使用流,但如果您更喜欢普通的java方式,那就容易多了。 如果我正确理解你的问题,那么你想要构建的方法。您可能需要进行一些调整以使其更快。
if(foo != null)
{
bar = foo.buz();
}
测试:
public Map<String, List<Map<String, String>>> doGrouping(List<String> columns, List<Map<String, String>> data) {
Map<String, List<Map<String, String>>> output = new HashMap<>();
for (Map<String, String> map : data) {
String key = "";
for(String column : columns) key += "".equals(key) ? (map.get(column)) : (":" + map.get(column));
output.computeIfAbsent(key, k -> Arrays.asList(map));
}
return output;
}