Предполагая, что у вас нет повторяющихся записей (по ключу столбца слияния), вы можете использовать такой метод для слияния.
Это создает карту ключа mergeColumn
для полной картыпо строке в одном из списков, а затем использует его для поиска при объединении путем итерации по другой карте.
static List<Map<String, String>> merge(List<Map<String, String>> left,
List<Map<String, String>> right, String joinColumnTableLeft,
String joinColumnTableRight) {
Map<String, Map<String, String>> rightById = right.stream()
.collect(Collectors.toMap(m -> m.get(joinColumnTableRight),
Function.identity()));
return left.stream()
.filter(e -> rightById.containsKey(e.get(joinColumnTableLeft)))
.map(l -> {
Map<String, String> all = new HashMap<>();
all.putAll(l);
all.putAll(rightById.get(l.get(joinColumnTableLeft)));
return all;
})
.collect(Collectors.toList());
}
В качестве теста:
Map<String, String> left1 = new HashMap<>(), right1 = new HashMap<>();
left1.put("a", "A");
left1.put("b", "B");
left1.put("c", "C");
right1.put("a", "A");
right1.put("d", "B");
Map<String, String> left2 = new HashMap<>(), right2 = new HashMap<>();
left2.put("a", "AA");
left2.put("b", "BB");
left2.put("c", "CC");
right2.put("a", "AA");
right2.put("d", "BB");
System.out.println(merge(Arrays.asList(left1, left2),
Arrays.asList(right1, right2), "a", "a"));
Вывод: [{a=A, b=B, c=C, d=B}, {a=AA, b=BB, c=CC, d=BB}]
Порядок записей не важен.Просто отметьте, что это предполагает, что нет никаких перекрывающихся ключей, кроме столбца соединения.В противном случае вы можете собирать пары карт вместо вызова putAll
на новой карте.
Следующее будет поддерживать дубликаты ключей соединения (и будет производить декартово произведение для всех записей на ключ):
static List<Map<String, String>> merge(List<Map<String, String>> left,
List<Map<String, String>> right,
String joinColumnTableLeft, String joinColumnTableRight) {
Map<String, List<Map<String, String>>> rightById = right.stream()
.collect(Collectors.groupingBy(m -> m.get(joinColumnTableRight)));
return left.stream()
.filter(e -> rightById.containsKey(e.get(joinColumnTableLeft)))
.flatMap(l -> rightById.get(l.get(joinColumnTableLeft)).stream()
.map(r -> {
Map<String, String> all = new HashMap<>();
all.putAll(l);
all.putAll(r);
return all;
}
)
).collect(Collectors.toList());
}