我正在处理 Person
数据的 Stream
,并且遇到了与数据相关的分区问题。
我有一个Stream
数据,我将在下面的表格中表示它:
ID Name Ticket IsEmployee
1 A Y Y
2 B
3 C Y
4 D
我正在尝试返回一个按以下顺序排序的List
:
- 无论他们是否是员工
- 如果他们有任何门票
- 然后按名字
我已经研究了 Collections.groupBy
和 Collections.partitioningBy
,但到目前为止还无法得出正确的结果。
我的期望是按以下顺序返回列表(按 ID):
1 [name="A",Ticket="**[100,101]**", IsEmployee="**Y**"],
3 [name="C",Ticket="**[200,201]**", IsEmployee=""],
2 [name="**B**",Ticket="", IsEmployee=""],
4 [name="D",Ticket="", IsEmployee=""]
对于如何在不完全分解 Stream 的情况下实现这一点有什么想法吗?
下面是我的人的样子:
public class Person {
private long id;
private String name;
private List<Ticket> tickets;
private String employeeType; // This is just a 'Y'/'N' value. This property has morphed into something else but I'm stuck using it.
public long getId(){
return id;
}
public String getName(){
return name;
}
public List<Ticket> getTickets(){
return tickets;
}
public String getEmployeeType(){
return id;
}
// Setters are the exact same as getters, meaning I have no transient methods
}
最佳答案
既然你说“我试图返回一个按...排序的列表”,那么不清楚你为什么开始寻找分组或分区,而不是准确地瞄准你的问题描述是什么,而是获取一个列表
并按你的标准对其进行排序:
// collect into a mutable List, if it isn’t a mutable List in the first place
List<Person> list=stream.collect(Collectors.toCollection(ArrayList::new));
// sort by your specified criterie (note: false < true)
list.sort(Comparator.comparing((Person p) -> !p.getEmployeeType().equals("y"))
.thenComparing(p -> p.getTickets().isEmpty())
.thenComparing(Person::getName) );
您还可以将操作指定为 Stream 操作的一部分,例如
List<Person> list=stream
.sorted(
Comparator.comparing((Person p) -> !p.getEmployeeType().equals("y"))
.thenComparing(p -> p.getTickets().isEmpty())
.thenComparing(Person::getName) )
.collect(Collectors.toList());
但没有技术上的好处。 Stream 实现必须将整个内容收集到内部临时缓冲区中,以便在将其收集(即复制)到生成的 List
之前对其进行排序。 ArrayList 的就地排序可能会减少甚至不需要数据复制(这对于四个元素来说并不重要,但一般情况下)。
关于java - 对流进行分区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40368701/