Я не могу понять концепцию необязательных и потоков при использовании с map () против flatMap ().
Я понимаю этот код:
public String getCarInsurance(Optional<Person> optPerson) {
return optPerson.flatMap(Person::getCar) //Returns Optional<Car>
.flatMap(Car::getInsurance) //Returns Optional<Insurance>, .map would give Optional<Optional<Insurance>>
.map(Insurance::getName) //no need for flatmap because getName returns String, not Optional<String>
.orElse("UNKNOWN"); //returns value or Unknown
}
Но я не могу понять этот код:
public Set<String> getCarInsuranceNames(List<Person> persons) {
return persons.stream()
.map(Person::getCar) //Convert the list of persons into Stream Optional<Car>
.map(optCar -> optCar.flatMap(Car::getInsurance)) //I don't understand this line
.map(optIns -> optIns.map(Insurance::getName))
.flatMap(Optional::stream)
.collect(toSet());
}
изменить:
Почему в этом случае нам нужно .map(optCar -> optCar.flatMap(Car::getInsurance))
, получить Stream Optional<Insurance>
? Но в первом коде .map(Car::getInsurance)
было достаточно, чтобы получить Optional<Insurance>
.
Я понимаю, почему нам нужно .flatmap
вместо .map
в первом коде, но я не могу понять конвейер Stream во второй код.
Во втором коде .map(Person::getCar)
возвращает Stream Optional<Car>
, а затем мы используем .map(optCar -> optCar.flatMap(Car::getInsurance))>
, чтобы получить Stream Optional<Insurance>
. Почему бы .flatmap(Car::getInsurance)
не получить нам Stream Optional<Insurance>
? Это то, что я не понимаю.
edit: Классы доменов ниже, если необходимо.
public class Insurance {
public String getName() {
return name;
}
}
public class Car {
Optional<String> name;
public Optional<String> getName() {
return name;
}
public class Person {
Optional<Car> car;
public Optional<Car> getCar(){
return car;
}
}