Java 8-разница между необязательными.flatmap и необязательно.карта



в чем разница между этими двумя методами: необязательно.flatMap () и необязательно.карта()?



пример был бы признателен.

538   4  

4 ответов:

использовать map если функция возвращает нужный вам объект или flatMap если функция возвращает Optional. Например:

public static void main(String[] args) {
  Optional<String> s = Optional.of("input");
  System.out.println(s.map(Test::getOutput));
  System.out.println(s.flatMap(Test::getOutputOpt));
}

static String getOutput(String input) {
  return input == null ? null : "output for " + input;
}

static Optional<String> getOutputOpt(String input) {
  return input == null ? Optional.empty() : Optional.of("output for " + input);
}

Оба оператора печати печатают одно и то же.

они оба принимают функцию от типа необязательного к чему-то.

карта применяет функцию "как есть" на необязательном у вас есть:

if (optional.isEmpty()) return Optional.empty();
else return Optional.of(f(optional.get()));

что произойдет, если ваша функция-это функция от T -> Optional<U>? Ваш результат теперь Optional<Optional<U>>!

что это flatMap О: если ваша функция уже возвращает Optional,flatMap немного умнее и не дважды обернуть его, возвращая Optional<U>. Это композиция из двух функциональных идиом: map и flatten.

Примечание: - ниже приведена иллюстрация функции map и flatmap, в противном случае необязательный в первую очередь предназначен для использования только в качестве возвращаемого типа.

как вы уже знаете, Optional-это своего рода контейнер, который может содержать или не содержать один объект, поэтому его можно использовать везде, где вы ожидаете нулевое значение(вы можете никогда не увидеть NPE, если используете Optional правильно). Например, если у вас есть метод, который ожидает объект person, который может быть nullable вы можете написать метод что-то вроде этого:

void doSome(Optional<Person> person){
  /*and here you want to retrieve some property phone out of person
    you may write something like this:
  */
  Optional<String> phone = person.map((p)->p.getPhone());
  phone.ifPresent((ph)->dial(ph));
}
class Person{
  private String phone;
  //setter, getters
}

здесь вы вернули строковый тип, который автоматически завернут в необязательный тип.

Если класс person выглядел так, то есть телефон также не является обязательным

class Person{
  private Optional<String> phone;
  //setter,getter
}

в этом случае вызов функции map обернет возвращаемое значение в необязательное и даст что-то вроде:

Optional<Optional<String>> 
//And you may want Optional<String> instead, here comes flatMap

void doSome(Optional<Person> person){
  Optional<String> phone = person.flatMap((p)->p.getPhone());
  phone.ifPresent((ph)->dial(ph));
}

PS; Никогда не вызывайте метод get (если вам нужно) по желанию, не проверяя его с помощью isPresent (), если вы не можете жить без возникновению исключительных ситуаций типа NullPointerException.

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

карта - обертывает результат в необязательный.

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value)); //<--- wraps in an optional
    }
}

flatMap - возвращает ' raw ' объект

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value)); //<---  returns 'raw' object
    }
}

Comments

    Ничего не найдено.