Java 对流进行分区

Java 对流进行分区,java,java-stream,Java,Java Stream,我正在处理一个流的人数据,我遇到了一个与数据相关的分区问题 我有一个数据流,我将在下表中表示: ID Name Ticket IsEmployee 1 A Y Y 2 B 3 C Y 4 D 我试图返回一个按以下顺序排序的列表: 不管他们是不是员工 如果他们有票的话 然后按名字 我已经调查了集合。groupBy和集合。partitioning by,但到目前为止还没有得出正确的结果 我的期望是按以下顺序(按ID)返回列表: 你有没有

我正在处理一个
数据,我遇到了一个与数据相关的分区问题

我有一个
数据流
,我将在下表中表示:

ID  Name Ticket IsEmployee
1   A      Y        Y
2   B     
3   C      Y
4   D
我试图返回一个按以下顺序排序的
列表

  • 不管他们是不是员工
  • 如果他们有票的话
  • 然后按名字
  • 我已经调查了
    集合。groupBy
    集合。partitioning by
    ,但到目前为止还没有得出正确的结果

    我的期望是按以下顺序(按ID)返回列表:

    你有没有想过如何在不必完全分开流程的情况下实现这一点

    下面是我的人的长相:

    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
    }
    
    公共类人物{
    私人长id;
    私有字符串名称;
    私人名单门票;
    私有字符串employeeType;//这只是一个'Y'/'N'值。此属性已变形为其他属性,但我无法使用它。
    公共长getId(){
    返回id;
    }
    公共字符串getName(){
    返回名称;
    }
    公共列表getTickets(){
    回程票;
    }
    公共字符串getEmployeeType(){
    返回id;
    }
    //setter与getter完全相同,这意味着我没有瞬态方法
    }
    
    既然您说“我试图返回一个按…排序的列表”,那么不清楚您为什么开始寻找分组或分区,而不是确切地针对问题描述,获取一个
    列表
    ,并根据您的条件对其进行排序:

    // 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) );
    
    //如果一开始不是可变列表,则收集到可变列表中
    List List=stream.collect(Collectors.toCollection(ArrayList::new));
    //按指定的标准排序(注意:false!p.getEmployeeType().equals(“y”))
    .然后比较(p->p.getTickets().isEmpty())
    .然后比较(Person::getName));
    
    您还可以将该操作指定为流操作的一部分,例如

    List<Person> list=stream
        .sorted(               
            Comparator.comparing((Person p) -> !p.getEmployeeType().equals("y"))
                      .thenComparing(p -> p.getTickets().isEmpty())
                      .thenComparing(Person::getName) )
        .collect(Collectors.toList());
    
    List=stream
    .已分类(
    Comparator.comparing((Person p)->!p.getEmployeeType().equals(“y”))
    .然后比较(p->p.getTickets().isEmpty())
    .Then比较(Person::getName))
    .collect(Collectors.toList());
    
    但这并没有技术上的好处。流实现必须在内部将整个内容收集到临时缓冲区中,以便在将其收集(即复制)到结果
    列表中之前对其进行排序。
    ArrayList的就地排序
    可能不需要复制数据,甚至不需要复制数据(这对四个元素并不重要,但一般来说都很重要)。

    既然您说的是“我试图返回一个按…排序的列表”,那么不清楚您为什么开始寻找分组或分区,而不是针对,您的问题描述是关于什么的,请获取
    列表
    ,并根据您的标准对其进行排序:

    // 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) );
    
    //如果一开始不是可变列表,则收集到可变列表中
    List List=stream.collect(Collectors.toCollection(ArrayList::new));
    //按指定的标准排序(注意:false!p.getEmployeeType().equals(“y”))
    .然后比较(p->p.getTickets().isEmpty())
    .然后比较(Person::getName));
    
    您还可以将该操作指定为流操作的一部分,例如

    List<Person> list=stream
        .sorted(               
            Comparator.comparing((Person p) -> !p.getEmployeeType().equals("y"))
                      .thenComparing(p -> p.getTickets().isEmpty())
                      .thenComparing(Person::getName) )
        .collect(Collectors.toList());
    
    List=stream
    .已分类(
    Comparator.comparing((Person p)->!p.getEmployeeType().equals(“y”))
    .然后比较(p->p.getTickets().isEmpty())
    .Then比较(Person::getName))
    .collect(Collectors.toList());
    

    但这并没有技术上的好处。流实现必须在内部将整个内容收集到临时缓冲区中,以便在将其收集(即复制)到结果
    列表中之前对其进行排序。
    ArrayList的就地排序
    可能不需要太多数据复制,甚至不需要数据复制(这对四个元素并不重要,但一般来说)。

    stream.collect(partitionBy(Person::hasTicket,partitioning by(Person::isEmployee))
    工作吗?当你说你已经尝试了
    groupBy
    partitionBy
    ,你能详细说明一下吗?我试过的一个简单的例子是:
    personStream.stream().collect(p->Collectors.partitionby(p.getTickets.size()>0);
    @LouisWasserman,我希望我能使用
    Person::isEmployee
    Person::hasTickets
    ,但是我使用的数据(我在上面简化了)是一个集合,所以我必须测试它的大小你能用吗?
    stream.collect(partitionBy(Person::hasTicket,partitionBy(Person::isEmployee))
    工作吗?当你说你试过
    groupBy
    partitionBy
    时,你能详细说明一下吗?我试过的一个简单的例子是:
    personStream.stream().collect()(p->Collectors.partitioning by(p.getTickets.size()>0);
    @LouisWasserman,我希望我可以使用
    Person::isEmployee
    Person::hasTickets
    ,但是我正在处理的数据(我在上面简化了)是一个集合,所以我必须测试它的大小,你不用吗?>“流实现必须在内部将整个内容收集到临时缓冲区中,以便在收集之前对其进行排序”>您是100%正确的。我能够在SQL而不是Java>中解决此问题。”流实现必须在内部将整个内容收集到一个临时缓冲区中,以便在收集之前对其进行排序“>您是100%正确的。我能够在SQL中而不是在Java中解决这个问题