Java流中的三元操作员

发布于 2025-01-29 12:51:24 字数 2173 浏览 4 评论 0原文

我具有以下功能,该功能利用流和收集器来创建映射和基于布尔的执行中的不同之

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()));
    }

处如果/其他分支,

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

我是否尝试过移动iSmultSelection? :collect()中选中

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 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 ? : 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())));
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何其悲哀 2025-02-05 12:51:24

我发现Java编译器很难推断出从流到收集器流动的类型参数。您的两个用例之间的唯一区别是使用的收集器。我会将收集器拉到单独的方法中,以返回每种情况的适当收集器。这不仅有助于清理代码,而且提供收集器的方法的返回类型阐明了类型,避免了错误。

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()));
}

我什至会考虑将其进一步分解,也许将收藏家存储在田野中,而只是用名字返回。里面的三元人看起来仍然太忙了。或将一个返回一个if块,如果它掉落了,请返回另一个。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文