使用 Streams 对对象及其嵌套成员进行复杂排序

问题描述 投票:0回答:1

我有一个答案数组列表,每个答案要么不包含答案值,要么包含多个答案值。 AnswerValues 有一个 id。

我想要实现的目标如下:

  1. 遍历每个答案并按 id 升序对答案值进行排序。
  2. 按答案值之一的最小 ID 对答案进行排序。

到目前为止我尝试解决的问题是:

laneValues.setAnswers(laneValues.getAnswers().stream()
                    .sorted((e1, e2) -> e1.getAnswerValues().get(0).getId().compareTo(e2.getAnswerValues().get(0).getId())).toList());

问题:

  • 如果答案没有answerValues,则
    .get(0)
    会抛出NPE。
  • 需要首先按每个答案的 ID 对answerValues 进行排序。

理想的解决方案是什么样的?

java java-stream
1个回答
0
投票

我想我现在已经找到了适合我的问题的解决方案。但我将排序分为三个步骤:

我做的第一件事是按 ID 对answerValues 进行排序:

for (SrmQsRfiAnswer answer: laneValues.getAnswers()) {
    List <SrmQsRfiAnswerValue> answerValues = answer.getAnswerValues();
    answerValues.sort(Comparator.comparingLong(SrmQsRfiAnswerValue::getId));
}

现在每个答案的所有answerValues都按ID排序。然后我将所有答案放入一个 HashMap,并以答案 ID 作为键。

Map <Long, List< SrmQsRfiAnswer>> answerMap = laneValues.getAnswers().stream()
    .collect(Collectors.groupingBy(SrmQsRfiAnswer::getId));

在最后一步中,我使用自定义“比较器”按答案值的最低 ID 对映射中每个键的答案进行排序:

answerMap.values().forEach(listOfAnswers - > listOfAnswers.sort(Comparator.comparingLong(SrmQsRfiAnswer::getMinAnswerValueId)));

public class SrmQsRfiAnswer {
...
    public Long getMinAnswerValueId() {
        if (answerValues == null || answerValues.isEmpty()) {
            return Long.MAX_VALUE; // Return a high value for null or empty lists
        }
        return answerValues.stream()
            .mapToLong(SrmQsRfiAnswerValue::getId)
            .min()
            .orElse(Long.MAX_VALUE);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.