首页 > 解决方案 > 使用 Java8 Streams 将 Class Leader Id 置于列表顶部

问题描述

我有一个学生列表,我只想将 leaderId 放在同一个列表的顶部,以下仍然是使用 Java Streams 的剩余列表项。我尝试了以下逻辑,但没有按预期工作

List<Student> students = ....

Long leaderId = 123;

students.stream().sort((s1,s2) -> leaderId.equals(s1.getId()) || leaderId.equals(s2.getId()) ? 1: 0).collect(Collectors.toList());

谁能给我一些建议

例子

学生名单:

[{id:121, name:"John"}, {id:131, name:"Susan"}, {id:123, name:"Jacob"}, {id:155, name:"Sunny"}]

预期产出

[{id:123, name:"Jacob"}, {id:121, name:"John"}, {id:131, name:"Susan"}, {id:155, name:"Sunny"}]

标签: javasortingjava-8java-stream

解决方案


您必须首先编写自己的比较器,在使用它进行排序时将领导者放在列表的前面。然后你必须用它来对列表进行排序。我看不出在这里使用流有任何意义,因为迭代代码看起来更简单易读。这是它在实践中的样子。

static class LeaderFirstComparator implements Comparator<Student> {
    final long leaderId;

    LeaderFirstComparator(long leaderId) {
        this.leaderId = leaderId;
    }

    @Override
    public int compare(Student o1, Student o2) {
        if (o1.id == leaderId && o2.id != leaderId)
            return -1;
        else if (o1.id != leaderId && o2.id == leaderId)
            return 1;
        else
            return 0;
    }

}

和客户端代码:

students.sort(new LeaderFirstComparator(leaderId));

更新

如果第一个对象是领导者,那么它应该在第二个之前,因此根据合同返回 -1。否则,如果第二个对象是领导者,那么第一个对象应该在它之后,因此为 1。如果没有一个对象是领导者或两者都是领导者,则保留原始顺序。因此返回 0。

根据以下评论,您可以将其进一步简化为这一行:

students.sort(Comparator.comparing(s -> s.getId() != leaderId));

推荐阅读