Несколько вещей, которые могли бы немного упростить решение, были бы, учитывая, что карта output
является Map<String, Set<String>>
, а затем в качестве окончательного результата можно рассматривать ключи, которые полностью присутствуют в выходной карте, как пустые []
.
Map<String, List<String>> lookUpExclusives(Map<String, List<String>> input,
Map<String, Set<String>> output) {
return input.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream()
.filter(val -> !output.getOrDefault(e.getKey(),
Collections.emptySet()).contains(val))
.collect(Collectors.toList())));
}
Это вернет {A=[], B=[Box.txt], C=[Cow.txt, Cob.txt]}
из метода. С точки зрения сложности, это будет M
количество раз для каждого элемента в значении записи входной карты и для каждой из N
записей, так что и O(N*M)
, но это должно быть максимально возможная оптимизация сложности выполнения.
Теперь, когда у вас есть эта сложная среда выполнения, вы можете дополнительно связать другую потоковую операцию для фильтрации записей, которые не имеют соответствующих значений, оставшихся в результате (например, A=[]
). Этого можно достичь, добавив следующий код к вышеуказанному конвейеру после первого collect
:
.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Это приводит к сложности только как O(N*M)
+ O(N)
, что может быть эффективно выражено как * Только 1020 *. Преимущество здесь в том, что вы получаете результат в формате, который вы ожидали, например, {B=[Box.txt], C=[Cow.txt, Cob.txt]}
.