问题
Let's say I have such object:
public class Customer {
private Integer id;
private String country;
private Integer customerId;
private String name;
private String surname;
private Date dateOfBirth;
}
and I have a List<Customer>
. I would like to split such list with Java streams so that I would get a list of ids List<Integer>
, countries List<String>
, customerIds List<Integer>
etc.
I know that I could do it as simple as making 6 streams such as:
List<Integer> idsList = customerList.stream()
.map(Customer::getId)
.collect(Collectors.toList());
but doing it that many times that I have fields seems pretty dull. I was thinking about custom Collector but I could not come up with anything useful that would be both neat and efficient.
回答1:
For a type safe solution, you’d need to define a class holding the desired results. This type may also provide the necessary methods for adding another Customer
or partial result:
public class CustomerProperties {
private List<Integer> id = new ArrayList<>();
private List<String> country = new ArrayList<>();
private List<Integer> customerId = new ArrayList<>();
private List<String> name = new ArrayList<>();
private List<String> surname = new ArrayList<>();
private List<Date> dateOfBirth = new ArrayList<>();
public void add(Customer c) {
id.add(c.getId());
country.add(c.getCountry());
customerId.add(c.getCustomerId());
name.add(c.getName());
surname.add(c.getSurname());
dateOfBirth.add(c.getDateOfBirth());
}
public void add(CustomerProperties c) {
id.addAll(c.id);
country.addAll(c.country);
customerId.addAll(c.customerId);
name.addAll(c.name);
surname.addAll(c.surname);
dateOfBirth.addAll(c.dateOfBirth);
}
}
Then, you can collect all results like
CustomerProperties all = customers.stream()
.collect(CustomerProperties::new, CustomerProperties::add, CustomerProperties::add);
回答2:
You can create a method like so:
public <T> List<T> getByFieldName(List<Customer> customerList, Function<Customer, T> field){
return customerList.stream()
.map(field)
.collect(Collectors.toList());
}
Then just call your method with the field you want:
List<Integer> ids = getByFieldName(customerList, Customer::getId);
List<String> countries = getByFieldName(customerList, Customer::getCountry);
List<Integer> customerIds = getByFieldName(customerList, Customer::getCustomerId);
//...
来源:https://stackoverflow.com/questions/60266230/split-list-of-objects-into-multiple-lists-of-fields-values-using-java-streams