«Код старой школы» должен быть скорее
public Set<K> removeEntries(Map<K, ?> from) {
Set<K> fromKeys = from.keySet(), removedKeys = new HashSet<>(keysToRemove);
removedKeys.retainAll(fromKeys);
fromKeys.removeAll(removedKeys);
return removedKeys;
}
Поскольку вы сказали, что keysToRemove
довольно мало, затраты на копирование, вероятно, не имеют значения.В противном случае используйте цикл, но не выполняйте поиск по хэшу дважды:
public Set<K> removeEntries(Map<K, ?> from) {
Set<K> fromKeys = from.keySet();
Set<K> removedKeys = new HashSet<>();
for(K keyToRemove : keysToRemove)
if(fromKeys.remove(keyToRemove)) removedKeys.add(keyToRemove);
return removedKeys;
}
Вы можете выразить ту же логику, что и поток, как
public Set<K> removeEntries(Map<K, ?> from) {
return keysToRemove.stream()
.filter(from.keySet()::remove)
.collect(Collectors.toSet());
}
, но так как это состояние с состояниемфильтр, это очень не рекомендуется.Более чистым вариантом будет
public Set<K> removeEntries(Map<K, ?> from) {
Set<K> result = keysToRemove.stream()
.filter(from.keySet()::contains)
.collect(Collectors.toSet());
from.keySet().removeAll(result);
return result;
}
, и если вы хотите максимизировать «потоковое» использование, вы можете заменить from.keySet().removeAll(result);
на from.keySet().removeIf(result::contains)
, что довольно дорого, поскольку оно повторяется по большей картеили с result.forEach(from.keySet()::remove)
, который не имеет этого недостатка, но, тем не менее, не более читабелен, чем removeAll
.
В целом, «код старой школы» намного лучше, чем этот..