使用 Java Stream 从 ArrayList 获得最高分

我想通过 Id 获得最高分组。如果两个最高分相同,那么我想根据最低可选 ID 获得最高分。我想在 Java Stream 中获得它。到目前为止,我正在尝试以下代码这不起作用示例:


数组列表:


ID:1 Score:80 OptionalId:1

ID:1 Score:90 OptionalId:2

ID:1 Score:90 OptionalId:3

ID:2 Score:80 OptionalId:1

ID:2 Score:100 OptionalId:3

ID:2 Score: 100 可选 ID:5


结果应该是


ID:1 得分 90 OptionalId:2

ID 2 得分 100 OptionalId:3


Map<Long, Optional<Person>> result1 = records.stream()

                  .collect(Collectors.groupingBy(Person::getId,

                          Collectors.maxBy(Comparator.comparing(Person::getScore)),

                          Collector.minBy(Comparator.comparing(Person::getOptionalId))));



        for(Person ns: result1) {


            sb.append(ns.getBatchNumber());

            sb.append(',');


茅侃侃
浏览 325回答 3
3回答

慕哥9229398

我建议你从一个Comparator<Person>优先考虑最大值 score然后是最小值的自定义开始optionalId。为简洁起见,这是将其传递给变量的好方法:final Comparator<Person> comparator = Comparator&nbsp; &nbsp; .comparing(Person::getScore)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// descending score first&nbsp; &nbsp; .thenComparing(Comparator&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // then ..&nbsp; &nbsp; &nbsp; &nbsp; .comparing(Person::getOptionalId)&nbsp; &nbsp; &nbsp; &nbsp; // .. optionalId&nbsp; &nbsp; &nbsp; &nbsp; .reversed());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // .. but ascending现在使用一些收集器java流.Collectors::groupingBy按值和下游对所有Persons进行分组idCollectors::reducing将所有Person相同的 s减少id为一个,使用Comparator<Person>得到最高score和最低的一个optionalId。Collectors::collectingAndThenCollection<Optional<Person>>将结构从to展平,Collection<Person>因为任何减少操作都会导致Optional- 此步骤是可选的,可能会根据您的示例跳过。这是代码:Collection<Person> filtered = records.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Stream<Person>&nbsp; &nbsp; .collect(Collectors.groupingBy(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // from Map<Long, List<Person>>&nbsp; &nbsp; &nbsp; &nbsp; Person::getId,&nbsp; &nbsp; &nbsp; &nbsp; Collectors.collectingAndThen(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // .. downstream to ..&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Collectors.reducing((a, b) ->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // .. Map<Long, Optional<Person>>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; comparator.compare(a, b) > 0 ? a : b),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Optional::get))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // .. Map<Long, Person>&nbsp; &nbsp; .values();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// .. Collection<Person>[人 [id=1, score=90, optionalId=2], 人 [id=2, score=100, optionalId=3]]

有只小跳蛙

对于给定的 Id 值,必须有一个 Person。Id 值的存在完全取决于 Person。因此,如果存在 Id,则也必须存在 Person。因此,将 aOptional<Person>作为地图的值有什么意义。相比之下,仅将一个Person实例作为map. 在这里,我将toMap收集器与 一起使用BinaryOperator.maxBy来完成工作。这是它的外观。请注意如何将BinaryOperator.maxBy用作mergeFunction。Map<Integer, Person> maxPersonById = records.stream()&nbsp; &nbsp; .collect(Collectors.toMap(Person::getId, Function.identity(),&nbsp; &nbsp; &nbsp; &nbsp; BinaryOperator.maxBy(Comparator.comparing(Person::getScore)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .thenComparing(Comparator.comparing(Person::getOptionalId).reversed()))));这是上述给定输入的输出。{1=Person [id=1, score=90, optionalId=2], 2=Person [id=2, score=100, optionalId=3]}

月关宝盒

您可以尝试使用以下聚合的流代码ID,然后使用两级排序找到最大分数,首先是分数,然后是可选的 ID,以防分数平局:import static java.util.Collections.reverseOrder;import static java.util.Comparator.comparing;Map<Long, Optional<Person>> result1 = records.stream()&nbsp; &nbsp; .collect(Collectors.groupingBy(Person::getId,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Collectors.maxBy(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Comparator.comparing(Person::getScore)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .thenComparing(reverseOrder(comparing(Person::getOptionalId))))));Optional[ID: 1 Score: 90 OptionalId: 2]Optional[ID: 2 Score: 100 OptionalId: 3]这里的技巧是仅反转可选 ID 的排序顺序,我们希望它是升序的,而不是降序的。默认情况下排序顺序为降序,因为我们正在调用Collections.maxBy.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java