简体   繁体   中英

Ternary operator within Java Streams

I have the following function which utilizes streams and collectors to create a map and differs in execution based on a boolean input parameter isMultiSelectableQuiz :

private Map<Integer, Long> getCountPerAnswerChoice(boolean isMultiSelectableQuiz, int questionId, List<QuizResponse> quizResponses) {
     return isMultiSelectableQuiz
        ? quizResponses.stream()
            .flatMap(response -> response.getAnswersByQuestions().stream())
            .filter(answerByQuestion -> answerByQuestion.getQuestionId() == questionId)
            .collect(
                Collectors.flatMapping(
                    (QuizQuestionAnswer answerByQuestion) -> answerByQuestion.getAnswerSelectionsList().stream(),
                    Collectors.groupingBy(selection -> selection, Collectors.counting())))
        : quizResponses.stream()
            .flatMap(response -> response.getAnswersByQuestions().stream())
            .filter(answerByQuestion -> answerByQuestion.getQuestionId() == questionId)
            .collect(
                Collectors.groupingBy(QuizQuestionAnswer::getAnswerSelection, Collectors.counting()));
    }

Is there a way to simplify this code and make it more elegant as the following portion is repeated in both if/else branches

quizResponses.stream()
            .flatMap(response -> response.getAnswersByQuestions().stream())
            .filter(answerByQuestion -> answerByQuestion.getQuestionId() == questionId)

I have attempted moving the isMultiSelection ? : isMultiSelection ? : check within the collect() but that throws a compile time error

private Map<Integer, Long> getCountPerAnswerChoice(boolean isMultiSelectableQuiz, int questionId, List<QuizResponse> quizResponses) {
     return quizResponses.stream()
        .flatMap(response -> response.getAnswersByQuestions().stream())
        .filter(answerByQuestion -> answerByQuestion.getQuestionId() == questionId)
        .collect(
            isMultiSelectableQuiz
                ? Collectors.groupingBy(
                    QuizQuestionAnswer::getAnswerSelection, Collectors.counting())
                : Collectors.flatMapping(
                    (QuizQuestionAnswer answerByQuestion) -> answerByQuestion.getAnswerSelectionsList().stream(),
                    Collectors.groupingBy(selection -> selection, Collectors.counting())));
    }

I've found that the java compiler has difficulty inferring the type arguments as they flow from stream to collector. The only difference between your two use cases is the collector used. I would pull the collectors out into a separate method to return the appropriate collector for each case. This not only helps clean up the code, the return type of the method providing the collector clarifies the types, avoiding the error.

private Map<Integer, Long> getCountPerAnswerChoice(boolean isMultiSelectableQuiz,
        int questionId, List<QuizResponse> quizResponses) {
    return quizResponses.stream()
        .flatMap(response -> response.getAnswersByQuestions().stream())
        .filter(answerByQuestion -> answerByQuestion.getQuestionId() == questionId)
        .collect(getCollectorForQuizType(isMultiSelectableQuiz));
}

private Collector<? super QuizQuestionAnswer, ?, Map<Integer, Long>> getCollectorForQuizType(
        boolean isMultiSelectableQuiz) {
    return isMultiSelectableQuiz
        ? Collectors.groupingBy(QuizQuestionAnswer::getAnswerSelection, Collectors.counting())
        : Collectors.flatMapping(
            answerByQuestion -> answerByQuestion.getAnswerSelectionsList().stream(),
            Collectors.groupingBy(selection -> selection, Collectors.counting()));
}

I would even consider breaking it down further, perhaps storing the collectors in fields and just returning one by name. It still looks too busy to me with the ternary in there. Or return one inside an if block, and if it falls through, return the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM