Java 基于值拆分值列表

Java 基于值拆分值列表,java,collections,Java,Collections,我有一个对象列表(在本例中为Person),我希望根据值将它们拆分为一个list Person对象列表。在下面给出的示例中,我有一个名为name、id和Address的Person对象。address对象有一个门牌号,Street Id。现在我想使用collections API根据address对象中的Street Id对它们进行拆分。我尝试按分组,在集合中进行分区,但没有成功。我只想使用Java8。没有第三方 预期结果: [ [person1, person2, person3] , [pe

我有一个对象列表(在本例中为Person),我希望根据值将它们拆分为一个list Person对象列表。在下面给出的示例中,我有一个名为name、id和Address的Person对象。address对象有一个门牌号,Street Id。现在我想使用collections API根据address对象中的Street Id对它们进行拆分。我尝试按分组,在集合中进行分区,但没有成功。我只想使用Java8。没有第三方

预期结果:

[ [person1, person2, person3] , [person4, person5], [person6] ]
谢谢

package testapplication2;

import java.util.ArrayList;
import java.util.List;

/**
 *
 *
 */
public class JavaCollections {

  public static void main(String[] args) {
    JavaCollections c = new JavaCollections();
    c.test1();
  }

  public void test1() {
    List<Person> persons = new ArrayList<>();
    Address address1 = new Address(1, "X Street", 100);
    Address address2 = new Address(2, "X Street", 100);
    Address address3 = new Address(3, "X Street", 100);
    Address address4 = new Address(4, "Y Street", 101);
    Address address5 = new Address(5, "Y Street", 101);
    Address address6 = new Address(6, "Z Street", 102);
    persons.add(new Person(1, "P1", address1));
    persons.add(new Person(2, "P2", address2));
    persons.add(new Person(3, "P3", address3));
    persons.add(new Person(4, "P4", address4));
    persons.add(new Person(5, "P5", address5));
    persons.add(new Person(6, "P6", address6));
  }

  public class Person {

    public int personId;
    private String name;

    private Address address;

    public Person() {

    }

    public Person(int personId, String name, Address address) {
      super();
      this.personId = personId;
      this.name = name;
      this.address = address;
    }

    public int getPersonId() {
      return personId;
    }

    public void setPersonId(int personId) {
      this.personId = personId;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public Address getAddress() {
      return address;
    }

    public void setAddress(Address address) {
      this.address = address;
    }

    @Override
    public String toString() {
      return "Person{" + "personId=" + personId + ", name=" + name + ", address=" + address + '}';
    }

  }

  public class Address {

    public Address() {

    }

    public Address(int houseNumber, String streetName, int streetId) {
      this.houseNumber = houseNumber;
      this.streetId = streetId;
      this.streetName = streetName;
    }

    private int houseNumber;
    private String streetName;
    private int streetId;

    public int getHouseNumber() {
      return houseNumber;
    }

    public void setHouseNumber(int houseNumber) {
      this.houseNumber = houseNumber;
    }

    public String getStreetName() {
      return streetName;
    }

    public void setStreetName(String streetName) {
      this.streetName = streetName;
    }

    public int getStreetId() {
      return streetId;
    }

    public void setStreetId(int streetId) {
      this.streetId = streetId;
    }

    @Override
    public String toString() {
      return "Address{" + "houseNumber=" + houseNumber + ", streetName=" + streetName + ", streetId=" + streetId + '}';
    }

  }
}
包测试应用程序2;
导入java.util.ArrayList;
导入java.util.List;
/**
*
*
*/
公共类JavaCollections{
公共静态void main(字符串[]args){
JavaCollections c=新的JavaCollections();
c、 test1();
}
公共void test1(){
List persons=new ArrayList();
地址1=新地址(1,“X街”,100);
地址2=新地址(2,“X街”,100);
地址3=新地址(3,“X街”,100);
地址4=新地址(4,“Y街”,101);
地址5=新地址(101号Y街5号);
地址6=新地址(6,“Z街”,102);
新增(新人员(1,“P1”,地址1));
新增(新人员(2,“P2”,地址2));
新增(新人员(3,“P3”,地址3));
新增(新人员(4,“P4”,地址4));
新增(新人员(5,“P5”,地址5));
新增(新人员(6,“P6”,地址6));
}
公共阶层人士{
公共国际人格;
私有字符串名称;
私人地址;
公众人士(){
}
公共人物(int personId、字符串名称、地址){
超级();
this.personId=personId;
this.name=名称;
this.address=地址;
}
public int getPersonId(){
回归人格;
}
公共无效setPersonId(int personId){
this.personId=personId;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共广播getAddress(){
回信地址;
}
公共无效设置地址(地址){
this.address=地址;
}
@凌驾
公共字符串toString(){
返回“Person{”+“personId=“+personId+”,name=“+name+”,address=“+address+”}”;
}
}
公共课堂演讲{
公共广播{
}
公共地址(int houseNumber、字符串streetName、int streetId){
this.houseNumber=houseNumber;
this.streetId=streetId;
this.streetName=街道名称;
}
私人住宅号码;
私有字符串streetName;
私人内特街;
public int getHouseNumber(){
返回门牌号;
}
公共无效setHouseNumber(int houseNumber){
this.houseNumber=houseNumber;
}
公共字符串getStreetName(){
返回街道名称;
}
public void setStreetName(字符串streetName){
this.streetName=街道名称;
}
public int getStreetId(){
返回街;
}
公共无效设置树ID(内部树ID){
this.streetId=streetId;
}
@凌驾
公共字符串toString(){
返回“地址{“+”门牌号=“+houseNumber+”,streetName=“+streetName+”,streetId=“+streetId+”}”;
}
}
}
这应该可以做到:

    List< List<Person> > groups = new ArrayList<>( persons.stream().collect( 
    Collectors.groupingBy( p -> p.getAddress().getStreetId() ) ).values() );
final List<List<Person>> groupedPersons = persons.stream()
        .collect(Collectors.groupingBy(o -> o.address.streetId))
        .entrySet().stream()
        .map(Map.Entry::getValue).collect(Collectors.toList());
// Code for printing out
groupedPersons.forEach(people -> {
    System.out.print("[");
    System.out.print(people.stream().map(person -> String.format("person%d", person.personId)).collect(Collectors.joining(",")));
    System.out.print("]");
});
Listgroups=newarraylist(persons.stream().collect(
Collectors.groupby(p->p.getAddress().getStreetId()).values());
或者通过@shmosel:

    List< List<Person> > groups = persons.stream().collect( Collectors.collectingAndThen(
    Collectors.groupingBy( p -> p.getAddress().getStreetId() ), 
    m -> new ArrayList<>( m.values() ) ) );
Listgroups=persons.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(p->p.getAddress().getStreetId()),
m->newarraylist(m.values());
这应该可以做到:

    List< List<Person> > groups = new ArrayList<>( persons.stream().collect( 
    Collectors.groupingBy( p -> p.getAddress().getStreetId() ) ).values() );
final List<List<Person>> groupedPersons = persons.stream()
        .collect(Collectors.groupingBy(o -> o.address.streetId))
        .entrySet().stream()
        .map(Map.Entry::getValue).collect(Collectors.toList());
// Code for printing out
groupedPersons.forEach(people -> {
    System.out.print("[");
    System.out.print(people.stream().map(person -> String.format("person%d", person.personId)).collect(Collectors.joining(",")));
    System.out.print("]");
});
Listgroups=newarraylist(persons.stream().collect(
Collectors.groupby(p->p.getAddress().getStreetId()).values());
或者通过@shmosel:

    List< List<Person> > groups = persons.stream().collect( Collectors.collectingAndThen(
    Collectors.groupingBy( p -> p.getAddress().getStreetId() ), 
    m -> new ArrayList<>( m.values() ) ) );
Listgroups=persons.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(p->p.getAddress().getStreetId()),
m->newarraylist(m.values());

要实现这一点,您需要

  • 使用列表中的
  • 然后,
    groupBy
    地址的
    id
    ,所有拥有相同
    地址的人将一起出现在
    地图中
  • 然后获得
    (所有
    列表
    并将它们收集在一起)

要返回列表,您需要

  • 使用列表中的
  • 然后,
    groupBy
    地址的
    id
    ,所有拥有相同
    地址的人将一起出现在
    地图中
  • 然后获得
    (所有
    列表
    并将它们收集在一起)

要返回列表,您需要的解决方案是使用
stream().collect()
,并在
person.address.streetId
字段上调用
groupingBy

此代码应执行以下操作:

    List< List<Person> > groups = new ArrayList<>( persons.stream().collect( 
    Collectors.groupingBy( p -> p.getAddress().getStreetId() ) ).values() );
final List<List<Person>> groupedPersons = persons.stream()
        .collect(Collectors.groupingBy(o -> o.address.streetId))
        .entrySet().stream()
        .map(Map.Entry::getValue).collect(Collectors.toList());
// Code for printing out
groupedPersons.forEach(people -> {
    System.out.print("[");
    System.out.print(people.stream().map(person -> String.format("person%d", person.personId)).collect(Collectors.joining(",")));
    System.out.print("]");
});
更新:

如果要保留将其添加到初始列表的顺序,可以提供一个收集器,该收集器提供一个
java.util.LinkedHashSet
——一个保留唯一性和原始插入顺序的数据结构

分组代码如下所示:

final List<Set<Person>> groupedPersons = persons.stream()
        .collect(Collectors.groupingBy(o -> o.address.streetId, 
                Collector.of(() -> new LinkedHashSet<Person>(), HashSet::add, (s1, s2) -> {
            s1.addAll(s2);
            return s1;
        })))
        .entrySet().stream()
        .map(Map.Entry::getValue).collect(Collectors.toList());

您的需求的解决方案是使用
stream().collect()
groupby
调用
person.address.streetId
字段作为键

此代码应执行以下操作:

    List< List<Person> > groups = new ArrayList<>( persons.stream().collect( 
    Collectors.groupingBy( p -> p.getAddress().getStreetId() ) ).values() );
final List<List<Person>> groupedPersons = persons.stream()
        .collect(Collectors.groupingBy(o -> o.address.streetId))
        .entrySet().stream()
        .map(Map.Entry::getValue).collect(Collectors.toList());
// Code for printing out
groupedPersons.forEach(people -> {
    System.out.print("[");
    System.out.print(people.stream().map(person -> String.format("person%d", person.personId)).collect(Collectors.joining(",")));
    System.out.print("]");
});
更新:

如果要保留将其添加到初始列表的顺序,可以提供一个收集器,该收集器提供一个
java.util.LinkedHashSet
——一个保留唯一性和原始插入顺序的数据结构

分组