Java 8 Streams - 分层排序嵌套列表

标签 java sorting java-8 java-stream

给定以下示例,我想要一个对列表和嵌套列表进行排序的流函数

class Foo {
    public int sort;
    public List<Bar> bars;
    public Foo(int sort) {
        this.sort = sort;
    }

}

class Bar {
    public int sort;

    public Bar(int sort) {
        this.sort = sort;
    }
}

@Test
public void testSortering() {
    Foo foo = new Foo(1);
    Foo foo2 = new Foo(2);
    Bar bar = new Bar(1);
    Bar bar2 = new Bar(2);
    foo.bars = Arrays.asList(bar2, bar);
    foo2.bars = Arrays.asList(bar2, bar);

    List<Foo> foos = Arrays.asList(foo2, foo);

    //I would like to iterate foos and return a new foos sorted, and with bars sorted, so that this goes green

    assertEquals(1, foos.get(0).sort);
    assertEquals(1, foos.get(0).bars.get(0).sort);
    assertEquals(2, foos.get(0).bars.get(1).sort);
    assertEquals(2, foos.get(1).sort);
    assertEquals(1, foos.get(1).bars.get(0).sort);
    assertEquals(2, foos.get(1).bars.get(1).sort);

}

我试过这个:

List<List<Bar>> foosSorted = foos.stream()
        .sorted((o1, o2) -> Integer.compare(o1.sort, o2.sort))
        .map(f -> f.bars.stream().sorted((o1, o2) -> Integer.compare(o1.sort, o2.sort)).collect(Collectors.toList()))
        .collect(Collectors.toList());

但这会返回 Bar,而我想要一个 Foo 列表

最佳答案

下面会对每个foofoosbars进行排序,但是由于peek操作是改变 f,如果涉及并行性,这将产生意想不到的行为。

List<Foo> foosSorted = foos.stream()
           .sorted(Comparator.comparingInt(o -> o.sort))
           .peek(f -> {
                f.bars = f.bars.stream().sorted(Comparator.comparingInt(o -> o.sort)).collect(Collectors.toList());
            })
            .collect(Collectors.toList());

我建议您添加一个 Foo 的构造函数,采用 sortbars 并使用 map而不是 peek。这样,我们就不会改变任何 Foo 对象,因此可以毫无问题地并行运行。

List<Foo> foosSorted = foos.stream()
            .sorted(Comparator.comparingInt(o -> o.sort))
            .map(f -> {
                return new Foo(f.sort, f.bars.stream().sorted(Comparator.comparingInt(o -> o.sort)).collect(Collectors.toList()));
            })
            .collect(Collectors.toList());

与:

class Foo {
    public int sort;
    public List<Bar> bars;
    public Foo(int sort) {
        this.sort = sort;
    }
    public Foo(int sort, List<Bar> bars) {
        this.sort = sort;
        this.bars = new ArrayList<>(bars);
    }
}

关于Java 8 Streams - 分层排序嵌套列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32944984/

相关文章:

java - 循环遍历嵌套的 Retrofit JSON 结果

java - Spring MVC - 使用 @WebMvcTest 测试 Controller 时出现 @EnableGlobalMethodSecurity 错误 404

java - 避免在 Kotlin 中生成对象的静态实例

javascript - 在javascript中对天数进行排序

java - 在单个流中工作的多个线程

java - Maven pom无法编译文件

java - 按升序对数组元素进行排序

php - 如何按最接近的数字排序?

java - 一个 Action 的多个 Java 消费者

java - 我将如何使用 Java 8 和 lambda 打印 JVM 的系统属性?