Here is a very simple but not very effective solution:
static List<List<Integer>> mergeCollections(List<List<Integer>> input) {
List<List<Integer>> result = Collections.emptyList();
for (List<Integer> listInner : input) {
List<Integer> merged = Stream.concat(
result.stream()
.filter(list -> list.stream().anyMatch(listInner::contains))
.flatMap(List::stream),
listInner.stream()).distinct().collect(Collectors.toList());
result = Stream.concat(
result.stream()
.filter(list -> list.stream().noneMatch(merged::contains)),
Stream.of(merged)).collect(Collectors.toList());
}
return result;
}
, listInner , . , , [[1, 2], [4, 5], [7, 8]], listInner, [2, 3, 5, 7], [[1, 2, 3, 4, 5, 7, 8]] ( ). , listInner, , listInner merged. , merged, merged.
partitioningBy :
static List<List<Integer>> mergeCollections(List<List<Integer>> input) {
List<List<Integer>> result = Collections.emptyList();
for (List<Integer> listInner : input) {
Map<Boolean, List<List<Integer>>> map = result.stream().collect(
Collectors.partitioningBy(
list -> list.stream().anyMatch(listInner::contains)));
List<Integer> merged = Stream.concat(
map.get(true).stream().flatMap(List::stream),
listInner.stream()).distinct().collect(Collectors.toList());
result = Stream.concat(map.get(false).stream(), Stream.of(merged))
.collect(Collectors.toList());
}
return result;
}
map.get(true) , listInner map.get(false), , .
, , , , List<TreeSet<Integer>> , .