簡體   English   中英

根據值拆分值列表

[英]split List of values based on value

我有一個對象列表(在這種情況下為Person),我想根據值將它們分成一個列表Person對象。 在下面給出的示例中,我有一個帶有名稱,id和地址對象的Person對象。 地址對象具有門牌號碼,街道ID。 現在,我想使用集合API根據地址對象中的街道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 + '}';
    }

  }
}

應該這樣做:

    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() ) ) );

為此,您需要

  • 使用列表中的信息Stream
  • 然后groupByid的的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()更改為

public static List<Person> test1() {
    ...; 
    return persons;
} 

返回列表

滿足您需求的解決方案是使用stream().collect() ,並將person.address.streetId字段上的groupingBy調用作為鍵。

此代碼應執行以下操作:

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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM