split基于值的值列表

时间:2018-02-22 20:27:01

标签: java collections

我有一个对象列表(本例中为Person),我想根据值将它们拆分为一个列表Person对象列表。在下面给出的示例中,我有一个Person对象,其中包含name,id和Address对象。地址对象有一个门牌号码,街道ID。现在我想使用集合API在地址对象中基于Street Id拆分它们。我尝试分组,在集合中进行分区,但无法使其正常工作。我只想使用Java 8.没有第三方。

预期结果:

[ [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 + '}';
    }

  }
}

3 个答案:

答案 0 :(得分:2)

这应该这样做:

    List< List<Person> > groups = new ArrayList<>( persons.stream().collect( 
    Collectors.groupingBy( 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() ) ) );

答案 1 :(得分:1)

要实现这一目标,您需要

  • 使用列表的Stream
  • 然后groupBy id的{​​{1}},具有相同Address的所有人将在一起adressId
  • 然后你得到Map<Integer,List<Person>>(所有values并将它们聚集在一起)
List<Person>

public static void main(String[] args) { JavaCollections c = new JavaCollections(); List<Person> persons = c.test1(); List<List<Person>> res = new ArrayList<>(persons .stream() .collect(Collectors.groupingBy(o -> o.getAddress().getStreetId())).values()); System.out.println(test); } 更改为

test1()

返回列表

答案 2 :(得分:1)

您的要求的解决方案是stream().collect()groupingBy字段上使用person.address.streetId作为密钥使用{/ p}。

此代码应该这样做:

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("]");
});

以下是您可以运行的完整示例:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Partitions {

    public static void main(String[] args) {
        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));
        final List<List<Person>> groupedPersons = persons.stream()
            .collect(Collectors.groupingBy(o -> o.address.streetName))
            .entrySet().stream()
            .map(Map.Entry::getValue).collect(Collectors.toList());
        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("]");
        });

    }

    public static 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 static class Address {

        private int houseNumber;
        private String streetName;
        private int streetId;
        public Address() {

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

        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 + '}';
        }

    }
}

这将打印出来:

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

<强>更新

如果要保留添加到初始列表的顺序,可以提供一个提供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());

如果您在上面的示例中使用此代码,则会打印出来:

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