如何加入 java 中的两个地图?
How to join two maps in java?
我有以下地图:
LonM =[0, 0, 0, 0, 46, 15]
LatM =[5, 52, 35, 16, 37, 5]
并行地,我实现了一个复合模式class:
public class CompositeDataFrame implements IDataFrame, ICompositeDataFrame {
private String name;
private List <IDataFrame> children;
public CompositeDataFrame(String name){
this.name = name;
children = new LinkedList<>();
}
public void addChildren(IDataFrame child){
children.add(child);
}
并且得到如下查询方法:
public Map<Object, List<Object>> query(String keySelector, Predicate<Object> valuePredicate) {
Map<Object, List<Object>> result = new HashMap<>();
for (IDataFrame child:children)
result.putAll(child.query(keySelector, valuePredicate));
return result;
}
那么我们有下面调用查询方法的main:
CompositeDataFrame comp = new CompositeDataFrame("CompositeCities");
CompositeDataFrame comp1 = new CompositeDataFrame("2");
comp.addChildren(comp1);
comp1.addChildren(df);
comp.addChildren(df);
System.out.println("\n"+comp.query("LonM", entry -> ((Integer) entry) == 0));
问题是:如何连接每个 child 的地图?
PD:我使用了 putAll 方法,但它删除了具有相同键的映射,因此在这种情况下它没有用。
输出应该是:
LonM =[0, 0, 0, 0, 0, 0, 0, 0] LatM =[5, 52, 35, 16, 5, 52, 35, 16]
非常感谢!
是的,如果您使用 putAll
,它会删除具有相同键的映射条目。这就是地图的工作原理。您正在寻找的是一种按键对所有条目进行分组的方法,使用 Stream
s.
可以很容易地做到这一点
Map<Object, List<Object>> result = children.stream()
// Map from Stream<IDataFrame> to Stream<Map.Entry<Object, List<Object>>>
.flatMap(child -> child.query(keySelector, predicate).entrySet().stream())
// Collect back into a Map<Object, List<Object>> using groupinBy
.collect(Collectors.groupingBy(
// Use the key to group the values
Map.Entry::getKey,
// Since we don't want a Map<Object, List<List<Object>>> the List needs to be flattend using Collectors.flatMapping.
Collectors.flatMapping(entry -> entry.getValue().stream(), Collectors.toList())));
当然你不必使用Stream
s。
Map<Object, List<Object>> result = new HashMap<>();
for (IDataFrame child : children) {
// Loop over each entry of the query result.
child.query(keySelector, predicate).forEach((key, value) -> {
// computeIfAbsent creates a new List if none exists for the given key, otherwise it returns the existing one.
List<Object> valueList = result.computeIfAbsent(key, o -> new ArrayList<>());
// Finally just add all the values to the list.
valueList.addAll(value);
});
}
我有以下地图:
LonM =[0, 0, 0, 0, 46, 15]
LatM =[5, 52, 35, 16, 37, 5]
并行地,我实现了一个复合模式class:
public class CompositeDataFrame implements IDataFrame, ICompositeDataFrame {
private String name;
private List <IDataFrame> children;
public CompositeDataFrame(String name){
this.name = name;
children = new LinkedList<>();
}
public void addChildren(IDataFrame child){
children.add(child);
}
并且得到如下查询方法:
public Map<Object, List<Object>> query(String keySelector, Predicate<Object> valuePredicate) {
Map<Object, List<Object>> result = new HashMap<>();
for (IDataFrame child:children)
result.putAll(child.query(keySelector, valuePredicate));
return result;
}
那么我们有下面调用查询方法的main:
CompositeDataFrame comp = new CompositeDataFrame("CompositeCities");
CompositeDataFrame comp1 = new CompositeDataFrame("2");
comp.addChildren(comp1);
comp1.addChildren(df);
comp.addChildren(df);
System.out.println("\n"+comp.query("LonM", entry -> ((Integer) entry) == 0));
问题是:如何连接每个 child 的地图?
PD:我使用了 putAll 方法,但它删除了具有相同键的映射,因此在这种情况下它没有用。
输出应该是:
LonM =[0, 0, 0, 0, 0, 0, 0, 0] LatM =[5, 52, 35, 16, 5, 52, 35, 16]
非常感谢!
是的,如果您使用 putAll
,它会删除具有相同键的映射条目。这就是地图的工作原理。您正在寻找的是一种按键对所有条目进行分组的方法,使用 Stream
s.
Map<Object, List<Object>> result = children.stream()
// Map from Stream<IDataFrame> to Stream<Map.Entry<Object, List<Object>>>
.flatMap(child -> child.query(keySelector, predicate).entrySet().stream())
// Collect back into a Map<Object, List<Object>> using groupinBy
.collect(Collectors.groupingBy(
// Use the key to group the values
Map.Entry::getKey,
// Since we don't want a Map<Object, List<List<Object>>> the List needs to be flattend using Collectors.flatMapping.
Collectors.flatMapping(entry -> entry.getValue().stream(), Collectors.toList())));
当然你不必使用Stream
s。
Map<Object, List<Object>> result = new HashMap<>();
for (IDataFrame child : children) {
// Loop over each entry of the query result.
child.query(keySelector, predicate).forEach((key, value) -> {
// computeIfAbsent creates a new List if none exists for the given key, otherwise it returns the existing one.
List<Object> valueList = result.computeIfAbsent(key, o -> new ArrayList<>());
// Finally just add all the values to the list.
valueList.addAll(value);
});
}