Я бы посоветовал две вещи, чтобы сделать код более читабельным.Однако я бы не стал искусственно вводить Optional
.
Первый вариант: Objects::requireNonNullElse
в отдельном методе
List<Map<?, ?> bar() {
//...
return users.stream()
.filter(user -> id.equals(user.getId()))
.map(User::getData)
.map(Foo::nullSafeMap)
.collect(Collectors.toList());
}
private static Map<?, ?> nullSafeMap(final Map<?, ?> map) {
return Objects.requireNonNullElse(map, Collections.emptyMap());
}
Здесь вы должны использовать Objects::requireNonNullElse
,который возвращает объект, переданный в первом параметре, если он не null
, и объект, переданный в качестве второго параметра, если первый параметр null
.Наличие отдельного метода позволяет передавать ссылку на метод в Stream::map
, но требует, чтобы вы сначала отобразили экземпляры User
на их данные Map
.
Второй вариант: Inline Objects::requireNonNullElse
List<Map<?, ?> bar() {
//...
return users.stream()
.filter(user -> id.equals(user.getId()))
.map(User::getData)
.map(map -> Objects.requireNonNullElse(map, Collections.emptyMap()))
.collect(Collectors.toList());
}
Если вы не хотите, чтобы отдельный метод выполнял только эту единственную задачу, вы можете встроить метод и при желании даже удалитьпервое отображение в пользу .map(user -> Objects.requireNonNullElse(user.getData(), Collections.emptyMap()))
, но я бы посоветовал против этого.Не бойтесь делать несколько вызовов на Stream::map
, если это делает код более читабельным.
Заключение
Я бы предпочел бы первый вариант в качествеэто делает код очень читабельным: вы знаете, что сопоставляете экземпляры User
с данными, а затем делаете эти данные безопасными.
Второй вариант в порядке, но страдает от очень длинной строки, которая может сбить с толку на первый взгляд.Это намного лучше, чем многострочная лямбда. Я бы во что бы то ни стало избегал многострочных лямбд и всегда извлекал их содержимое в отдельный метод.
Одна вещь, которую вы могли бы улучшить, - это имя метода nullSafeMap
, так какчтобы избежать путаницы между Stream::map
и java.util.Map
.
Обратите внимание, что вам не нужно использовать Objects::requireNonNullElseGet
, поскольку Collections::emptyMap
- это легкий метод, который только приводит и возвращает константу:
public static final <K,V> Map<K,V> emptyMap() {
return (Map<K,V>) EMPTY_MAP;
}
Objects::requireNonNullElseGet
сделано для объектов по умолчанию, поиск или создание которых является тяжелым.