Assuming that you don't have duplicate entries (by the merge column key), you can use a method like this to merge.
This creates a map of the mergeColumn key to the full map by row in one of the lists, then uses that for lookup when merging by iterating through the other map.
static List> merge(List> left,
List> right, String joinColumnTableLeft,
String joinColumnTableRight) {
Map> 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 all = new HashMap<>();
all.putAll(l);
all.putAll(rightById.get(l.get(joinColumnTableLeft)));
return all;
})
.collect(Collectors.toList());
}
As a test:
Map 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 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"));
The output is: [{a=A, b=B, c=C, d=B}, {a=AA, b=BB, c=CC, d=BB}]
The order of entries isn't important, though. Just note that this assumes that there are no overlapping keys other than the join column. Otherwise, you may want to collect pairs of maps instead of calling putAll on a new map.
The following will support duplicate join keys (and will produce a cartesian product for all entries per key):
static List> merge(List> left,
List> right,
String joinColumnTableLeft, String joinColumnTableRight) {
Map>> 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 all = new HashMap<>();
all.putAll(l);
all.putAll(r);
return all;
}
)
).collect(Collectors.toList());
}