如何在将地图的值与另一个地图的值进行比较时将其设为空白?
How to make the value of a map blank while comparing it with the values of another map?
假设我有两个地图 region1、region2 并且都被声明为
LinkedHashMap<String, List<String>> region1 = new LinkedHashMap<>();
LinkedHashMap<String, List<String>> region2 = new LinkedHashMap<>();
region1 包含以下值:
region1 : {R1 = [A, B, C, D]}
region2 包含以下值:
region2 : {R2 = [G, A, D, B]}
以region1的值作为基值,遍历region2的值,不重复的值必须放在另一个map中,key为region2,region2的值不重复
所以地图region3包含
region3 : {R2 = [G]}
然后我们在另一个地图上迭代 region3 比较匹配值
map1 : {1 = [G, C]}
因为匹配到的值,我们需要在匹配到的值中加一个空格space。
因此 map1 包含值
map1 : {1=[ , C]}
编辑:优化。
Stream
而已。原始对象没有被修改。
不过有点长。
final Map<String, List<String>> region1 = new LinkedHashMap<>();
region1.put("R1", new ArrayList<>(Arrays.asList("A", "B", "C", "D")));
final Map<String, List<String>> region2 = new LinkedHashMap<>();
region2.put("R2", new ArrayList<>(Arrays.asList("A", "G", "C", "B")));
region2.put("R3", new ArrayList<>(Arrays.asList("A", "G", "C", "B")));
final Stream<Entry<String, List<String>>> entries =
region1.values()
.stream()
.flatMap(values ->
region2.entrySet()
.stream()
.map(e -> {
final List<String> value =
e.getValue()
.stream()
.filter(v -> !values.contains(v))
.collect(toList());
return new SimpleEntry<>(e.getKey(), value);
})
);
final Map<String, List<String>> result = entries.collect(toMap(Entry::getKey, Entry::getValue));
这就是我喜欢 Stream
的原因。使用 类型推断 (Java 10+
) 它甚至更干净。
不使用流,可以这样解决:
public static void main(String[] args) {
// setup the input and output maps
LinkedHashMap<String, List<String>> region1 = new LinkedHashMap<>();
LinkedHashMap<String, List<String>> region2 = new LinkedHashMap<>();
LinkedHashMap<String, List<String>> region3 = new LinkedHashMap<>();
region1.put("R1", asList("A", "B", "C", "D"));
region2.put("R2", asList("G", "A", "D", "B"));
// for each key in region2
for(String key : region2.keySet()) {
// make a copy of the values for that key
List<String> values = new ArrayList<>(region2.get(key));
// remove all the duplicates from each of the lists in region1
for (List<String> baseValues : region1.values()) {
values.removeAll(baseValues);
}
// if there are any remaining list values
if (values.size() > 0) {
// put them into region3
region3.put(key, values);
}
}
System.out.println(region3);
}
假设我有两个地图 region1、region2 并且都被声明为
LinkedHashMap<String, List<String>> region1 = new LinkedHashMap<>();
LinkedHashMap<String, List<String>> region2 = new LinkedHashMap<>();
region1 包含以下值:
region1 : {R1 = [A, B, C, D]}
region2 包含以下值:
region2 : {R2 = [G, A, D, B]}
以region1的值作为基值,遍历region2的值,不重复的值必须放在另一个map中,key为region2,region2的值不重复
所以地图region3包含
region3 : {R2 = [G]}
然后我们在另一个地图上迭代 region3 比较匹配值
map1 : {1 = [G, C]}
因为匹配到的值,我们需要在匹配到的值中加一个空格space。
因此 map1 包含值
map1 : {1=[ , C]}
编辑:优化。
Stream
而已。原始对象没有被修改。
不过有点长。
final Map<String, List<String>> region1 = new LinkedHashMap<>();
region1.put("R1", new ArrayList<>(Arrays.asList("A", "B", "C", "D")));
final Map<String, List<String>> region2 = new LinkedHashMap<>();
region2.put("R2", new ArrayList<>(Arrays.asList("A", "G", "C", "B")));
region2.put("R3", new ArrayList<>(Arrays.asList("A", "G", "C", "B")));
final Stream<Entry<String, List<String>>> entries =
region1.values()
.stream()
.flatMap(values ->
region2.entrySet()
.stream()
.map(e -> {
final List<String> value =
e.getValue()
.stream()
.filter(v -> !values.contains(v))
.collect(toList());
return new SimpleEntry<>(e.getKey(), value);
})
);
final Map<String, List<String>> result = entries.collect(toMap(Entry::getKey, Entry::getValue));
这就是我喜欢 Stream
的原因。使用 类型推断 (Java 10+
) 它甚至更干净。
不使用流,可以这样解决:
public static void main(String[] args) {
// setup the input and output maps
LinkedHashMap<String, List<String>> region1 = new LinkedHashMap<>();
LinkedHashMap<String, List<String>> region2 = new LinkedHashMap<>();
LinkedHashMap<String, List<String>> region3 = new LinkedHashMap<>();
region1.put("R1", asList("A", "B", "C", "D"));
region2.put("R2", asList("G", "A", "D", "B"));
// for each key in region2
for(String key : region2.keySet()) {
// make a copy of the values for that key
List<String> values = new ArrayList<>(region2.get(key));
// remove all the duplicates from each of the lists in region1
for (List<String> baseValues : region1.values()) {
values.removeAll(baseValues);
}
// if there are any remaining list values
if (values.size() > 0) {
// put them into region3
region3.put(key, values);
}
}
System.out.println(region3);
}