2

我有一个整数输入,我想在所有奇数之前按升序对所有偶数进行排序,并保留赔率顺序。我很确定我可以通过收集器和/或下游收集器实现这一目标,但我不知道该怎么做。我想知道如何对错误列表进行排序,因此如果可能的话,我可以在一行中实现它。因此,在分组之后,我希望将错误列表按升序排序,而另一个(真实赔率列表)保持不变,并且在此转换之后能够将它们平面映射到一个列表中。

例子:

输入是:

1 6 2 3 4 5
Map<Boolean, List<Integer>> collect = Arrays
        .stream(bf.readLine().split("\\s+"))
        .map(Integer::parseInt)
        .collect(Collectors.groupingBy(integer -> integer % 2 != 0));

System.out.println(collect);

上面代码的输出是:

{false=[6, 2, 4], true=[1, 3, 5]}

这行条目应变为:

{false=[2, 4, 6], true=[1, 3, 5]}

转换后。

输出应该是先于赔率的偶数,并按升序排序,同时保持赔率的顺序,如下所示:

2 4 6 1 3 5
4

3 回答 3

1

使用需要下游收集器groupingBy的重载

例如:

groupingBy(
    integer -> integer % 2 != 0,
    collectingAndThen(
        toList(),
        list -> list.stream().sorted().collect(toList()))
于 2021-04-30T12:45:59.797 回答
1

您实际上不需要分组。如果流是有序的,则该Stream.sorted方法是稳定的排序。

您只需要一个比较器,例如:

Comparator.comparingInt(x -> x % 2)
    // if it is even, order by natural order, otherwise they are "equal", so we map to a constant
    .thenComparingInt(x -> x % 2 == 0 ? x : 0)

例子:

Stream.of(3, 6, 2, 1, 4, 5).sorted(
    Comparator.<Integer>comparingInt(x -> x % 2)
        .thenComparingInt(x -> x % 2 == 0 ? x : 0))
    .forEachOrdered(System.out::println);

印刷:

2
4
6
3
1
5

如果你想要一个Map<Boolean, List<Integer>>,你可以按奇偶校验分区(这将保证false键总是存在于映射中),然后对与关联的列表进行排序false

Map<Boolean, List<Integer>> partitions = Stream.of(3, 6, 2, 1, 4, 5).collect(
    // collects to ArrayList to guarantee that it is mutable
    Collectors.partitioningBy(x -> x % 2 != 0, Collectors.toCollection(ArrayList::new))
);
partitions.get(false).sort(Comparator.naturalOrder());
于 2021-04-30T12:52:22.630 回答
1

Collectors.teeing使用Java 12 及更高版本以复杂的方式解决简单问题的唯一乐趣:

List<Integer> list = List.of(3, 6, 2, 1, 4, 5);

List<Integer> result = 
    list.stream()
        .collect(Collectors.teeing(
                    Collectors.filtering(i -> i % 2 == 0, Collectors.toList()), 
                    Collectors.filtering(i -> i % 2 != 0, Collectors.toList()), 
                    (List<Integer> evens, List<Integer> odds) -> {
                        List<Integer> merged = new ArrayList<>();
                        evens.sort(Comparator.naturalOrder());
                        merged.addAll(evens);
                        merged.addAll(odds);
                        return merged;
                    }
        ));

System.out.println(result);
于 2021-04-30T13:30:38.003 回答