如何用一条线实现这一目标?
我目前正在尝试这样做
示例:
{{"id" :"2", values: ["10","11", "12"]} , {"id" : "3", values : ["23"]}}
到
{{"id" :"2","value": "10"},{"id": "2","value":"11"},
{"id" :"3","value":"23"} , {"id" : "2", "value":"12"}}
我的java代码是
Map<Integer, List<Integer>> attrMap = new HashMap<>();
//getAllData() & item.getValues() both returns List
getAllData().forEach(item - > {
item.getValues().forEach(val - > {
attrMap.computeIfAbsent(item.getId(), (k) - >
new ArrayList < > ()).add(val.getValue());
});
});
我怎么能只做一行?
答案 0 :(得分:5)
由于ID是唯一的,您可以像
那样进行Map<Integer, List<Integer>> attrMap = getAllData().stream()
.collect(Collectors.toMap(
item -> item.getId(),
item -> item.getValues().stream().map(i->i.getValue()).collect(Collectors.toList())));
但是,当然,这仍然具有两个嵌套循环的性能特征。但它会支持并行处理,但我怀疑你的数据是否足以从并行处理中获益。
此外,请注意,生成的地图仍然在结构上与您的第一个模式匹配,
{{"id" :"2", values: ["10","11", "12"]} , {"id" : "3", values : ["23"]}}
您刚刚将item
转换为结果Map
和val
的条目List<Integer>
的元素。
答案 1 :(得分:1)
假设你有这样的输入:
static class Data {
private final int id;
private final List<Integer> values;
public int getId() {
return id;
}
public List<Integer> getValues() {
return values;
}
public Data(int id, List<Integer> values) {
super();
this.id = id;
this.values = values;
}
}
可以通过以下方式完成:
List<SimpleEntry<Integer, Integer>> result = Arrays.asList(
new Data(2, Arrays.asList(10, 11, 12)),
new Data(3, Arrays.asList(23)))
.stream()
.flatMap(d -> d.getValues().stream().map(x -> new AbstractMap.SimpleEntry<>(d.getId(), x)))
.collect(Collectors.toList());
System.out.println(result); // [2=10, 2=11, 2=12, 3=23]
我正在收集Pair
或AbstractMap.SimpleEntry
的内容。