Optional.orElse: как продолжить поток? - PullRequest
0 голосов
/ 03 октября 2018

Я хотел бы использовать потоковый подход, но я чувствую, что он несколько неоптимален.Я хотел бы избежать путаницы

.map(Optional::of)

Можно ли сделать метод № 2 ниже, чтобы избежать этой дополнительной путаницы, есть ли дополнительный метод, который я мог бы использовать для достижения того, что я хочу?

// Either map can be null, empty, or have the value for key
Map<String,String> map1 =  
Map<String,String> map2 = 


// Method #1
String value1 = null;
if (map1 != null) {
   value1 = map1.get(key);
}

if (value1 == null) {
   if (map2 != null) {
      value1 = map2.get(key);
   }
}

if (value1 == null) value1 = "default";

// Method #2
String value2 = Optional.ofNullable(map1)
    .map(map -> map.get(key))
    .map(Optional::of)
    .orElse(Optional.ofNullable(map2).map(map -> map.get(key)))
    .orElse("default");


assertEquals(value1, value2);

Я хотел бы иметь что-то вроде этого:

Optional.ofNullable(map1)
    .map(map -> map.get(key))
    .orOptional(Optional.ofNullable(map2).map(map -> map.get(key)))
    .orElse("default");

Где orOptional будет выглядеть примерно так: // Если значение присутствует в этом Необязательном, возвращает этот необязательный, в противном случае возвращает возвратный параметр Необязательный orOptional (Необязательный запасной вариант)

Редактировать 2018-10-15: Чтобы не застрять на том факте, что я использовал карты в примере, давайте предположим, что это всего лишь некоторые bean-компоненты с getter для значения.Либо бин может быть нулевым, либо значения, возвращаемые получателями, могут быть нулевыми.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Существует фундаментальная ошибка проектирования, когда переменные карты становятся равными null.

Если вы не можете исправить источник карт, вам следует как минимум ввести локальные переменные, содержащие не null отображает как можно раньше при обработке.

Map<String,String> m1 = map1 == null? Map.of(): map1, m2 = map2 == null? Map.of(): map2;

Map.of() требует Java 9. В Java 8 вместо этого можно использовать Collections.emptyMap().

Тогда ваша задачапросто как

String value1 = m1.getOrDefault(key, m2.getOrDefault(key, "default"));
0 голосов
/ 03 октября 2018

вам не нужно

.map(map -> map.get(key))
        .map(Optional::of)

Optional.map также возвращает Optional.Вы можете просто написать

Optional.ofNullable(map1)
                .map(map -> map.get(key))
                .orElseGet(() ->
                        Optional.ofNullable(map2)
                                .map(map -> map.get(key)).orElse("default")
                );

Кроме того, вы можете создать поток карт и затем сделать некоторые преобразования:

Stream.of(map1, map2)
  .filter(Objects::nonNull)
  .map(m -> m.get(key))
  .filter(Objects::nonNull)
  .findFirst()
  .orElse("default");
...