Java 8 Optional и flatMap - какво не е наред?

Част от кода:

public class Player {
    Team team;
    String name;
}

public class Team {
    List<Player> players;
}

public class Demo {

    @Inject
    TeamDAO teamDAO;

    @Inject
    PlayerDAO playerDAO;

    List<String> findTeamMatesNames(String playerName) {
        Optional<Player> player = Optional.ofNullable(playerDAO.get(playerName));

        return player.flatMap(p -> teamDAO.findPlayers(p.team))
            .map(p -> p.name)
            .orElse(Collections.emptyList());
    }
}

Защо не мога да направя това? В метода flatMap получавам грешка „Несъответствие на типа: не може да се преобразува от списък в незадължителен“

Моята цел е:

  1. Ако опцията присъства, искам да получа списък с елементи въз основа на това незадължително свойство на обект

  2. Ако не е задължително, искам да върна празен списък


person Dariusz Mydlarz    schedule 08.10.2014    source източник
comment
Каква грешка получавате?   -  person talex    schedule 08.10.2014
comment
Каква грешка получавате? И какво прави teamDAO.finPlayers?   -  person user2504380    schedule 08.10.2014
comment
Откъде идва team в findTeamMatesNames?   -  person coolcfan    schedule 08.10.2014
comment
Не е важното какво питаш. В flatMap получавам: Несъответствие на типа: не може да се преобразува от List‹Player› в Optional‹Object›   -  person Dariusz Mydlarz    schedule 08.10.2014
comment
@coolcfan Кодът му е повреден, отборът трябва да е играч.   -  person Dirk Lachowski    schedule 08.10.2014
comment
Изглежда, че смесвате поток и незадължителен apis. flatMap() в Optional е за разопаковане на вложени опции, но вашата ламбда връща списък с играчи, а не Optional‹Player›.   -  person Dirk Lachowski    schedule 08.10.2014
comment
@coolcfan съжалявам, направих грешка, сега трябва да е наред   -  person Dariusz Mydlarz    schedule 08.10.2014
comment
@DirkLachowski как мога да постигна целта си?   -  person Dariusz Mydlarz    schedule 08.10.2014


Отговори (1)


Можете да използвате map, за да извършите желаната операция. Операцията map няма да се осъществи, ако Optional е празно, но оставете отново празно Optional. Можете да предоставите резервната стойност след това:

player.map(p -> teamDAO.findPlayers(p.team)).orElse(Collections.emptyList())

Преобразуването от List на Player към List на името на играча Strings не може да бъде извършено от Optional; това е Stream задача:

Optional<Player> player = Optional.ofNullable(playerDAO.get(playerName));
return player.map(p -> teamDAO.findPlayers(p.team)
                           .stream().map(tp -> tp.name).collect(Collectors.toList()))
             .orElse(Collections.emptyList());
person Holger    schedule 08.10.2014
comment
Не знаех, че трябва да извърша следващите операции в първата функция на картата. Благодаря! - person Dariusz Mydlarz; 08.10.2014
comment
@dmydlarz: възможно е да го направите и след това, напр. player.map(p -> teamDAO.findPlayers(p.team)).orElse(Collections.emptyList()) .stream().map(tp -> tp.name).collect(Collectors.toList()) има същата семантика, но би означавало ненужна операция за събиране, извършена върху празния поток в случай на празен Optional. - person Holger; 08.10.2014