ИМХО потоковое не так уж плохая идея. Там нет плохих инструментов. Это зависит от того, как вы их используете.
В этом конкретном случае я бы выделил повторяющийся шаблон в служебный метод:
public static <K, V1, V2> Map<K, V2> transformValues(Map<K, V1> map, Function<V1, V2> transformer) {
return map.entrySet()
.stream()
.collect(toMap(Entry::getKey, e -> transformer.apply(e.getValue())));
}
Вышеприведенный метод может быть реализован с использованием любой подход, хотя я думаю, что Stream API
вполне подходит здесь.
После того, как вы определили метод утилит, его можно использовать так просто, как указано ниже:
Map<String, Map<String, CustomObj>> customMap =
transformValues(inputMap, attr -> transformValues(attr, this::getCustomObj));
Фактический трансформация фактически один лайнер. Таким образом, при правильном методе JavaDoc
для transformValues
код результата может быть легко читаем и обслуживаем.