Как сделать цепочку flatMap для цепочки объектов? - PullRequest
1 голос
/ 10 июня 2019

У меня есть следующие определения классов.

Insurance.java

package Chapter10;

public class Insurance {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Car.java

package Chapter10;

import java.util.Optional;

public class Car {

    private Optional<Insurance> insurance;

    public Optional<Insurance> getInsurance() {
        return insurance;
    }

    public void setInsurance(Optional<Insurance> insurance) {
        this.insurance = insurance;
    }
}

Person.java

package Chapter10;

import java.util.Optional;

public class Person {

    private Optional<Car> car;

    public Optional<Car> getCar() {
        return car;
    }

    public void setCar(Optional<Car> car) {
        this.car = car;
    }
}

Теперь у меня следующий основной класс, но я получаю исключение NullPoinerException для человека р.

package Chapter10;

import java.util.Optional;

public class OptionalTester {

    public static String getCarInsuranceName(Optional<Person> person) {
        return person.flatMap(Person::getCar)
                .flatMap(Car::getInsurance)
                .map(Insurance::getName)
                .orElse("Unknown");
    }

    public static void main(String[] args) {

        Insurance iffco = new Insurance();
        iffco.setName("IFFCO TOKIO");

        Insurance argo = new Insurance();
        argo.setName("HDFC ARGO");

        Car i10 = new Car();
        i10.setInsurance(Optional.of(iffco));

        Car santro = new Car();

        Person p = new Person();
        p.setCar(Optional.of(santro));

        Person p1 = new Person();
        p1.setCar(Optional.of(i10));

        System.out.println("---------------FROM PERSON GET INSURANCE----------------------");

        Optional<Insurance> optInsurance = Optional.ofNullable(argo);
        Optional<String> name = optInsurance.map(Insurance::getName);


        System.out.println(getCarInsuranceName(Optional.of(p1)));
        System.out.println(getCarInsuranceName(Optional.of(p)));

    }
}

Я получаю NPE за линию Optional.of (p), я знаю, что у p1 есть машина, и у этой машины есть страховка, чтобы она работала.

В случае p страховки нет, поэтому я получаю NPE. Но если я сделаю это с Optional.empty (), я правильно получу Unknown в качестве вывода.

Как мне сделать его более обобщенным, чтобы, если что-то сломалось, я получил Неизвестно ?

Ответы [ 3 ]

1 голос
/ 10 июня 2019

По сути, короткий ответ: «Вы не можете».Причиной этого является то, что Optional должна быть монадой (объект более высокого порядка, который для краткости позволяет вам заключать определенные операции в определенный контейнер), но в Java это не так.Следовательно, flatMap s не соединяются правильно.Для более продолжительного обсуждения вы можете увидеть https://www.sitepoint.com/how-optional-breaks-the-monad-laws-and-why-it-matters/

0 голосов
/ 12 июня 2019

Смена автомобиля должна работать.

Общественный автомобиль класса {

    private Insurance insurance;

    public Optional<Insurance> getInsurance() {
       return Optional.ofNullable(insurance);
    }

    public void setInsurance(Optional<Insurance> insurance) {
        this.insurance = insurance.orElse(null);
    }
}
0 голосов
/ 10 июня 2019

В santro страхование автомобиля - ноль.

import java.util.Optional;

открытый класс OptionalTester {

public static String getCarInsuranceName(Optional<Person> person) {
    return person.flatMap(Person::getCar)
            .flatMap(Car::getInsurance)
            .map(Insurance::getName)
            .orElse("Unknown");
}

public static void main(String[] args) {

    Insurance iffco = new Insurance();
    iffco.setName("IFFCO TOKIO");

    Insurance argo = new Insurance();
    argo.setName("HDFC ARGO");

    Car i10 = new Car();
    i10.setInsurance(Optional.of(iffco));

    Car santro = new Car();
    santro.setInsurance(Optional.of(argo)); \\ Insurence was null.

    Person p = new Person();
    p.setCar(Optional.of(santro));

    Person p1 = new Person();
    p1.setCar(Optional.of(i10));

    System.out.println("---------------FROM PERSON GET INSURANCE----------------------");

    Optional<Insurance> optInsurance = Optional.ofNullable(argo);
    Optional<String> name = optInsurance.map(Insurance::getName);


    System.out.println(getCarInsuranceName(Optional.of(p1)));
    System.out.println(getCarInsuranceName(Optional.of(p)));

}

}

...