使用Java流将对象列表拆分为多个字段值列表

3

假设我有这样的对象:

public class Customer {

    private Integer id;
    private String country;
    private Integer customerId;
    private String name;
    private String surname;
    private Date dateOfBirth;
}

我有一个 List<Customer>,我想要使用Java流将其拆分成多个列表,例如id的列表为 List<Integer>,国家的列表为 List<String>,客户ID的列表为 List<Integer> 等。

我知道可以通过创建6个流来实现此目的,例如:

List<Integer> idsList = customerList.stream()
        .map(Customer::getId)
        .collect(Collectors.toList());

但是,这样做很多次,我已经觉得相当乏味了。我在考虑自定义收集器,但我想不出任何有用的东西,既整洁又高效。


初始化3个列表,然后使用customerList.foreach将每个成员添加到相应的列表中,你觉得怎么样? - asfmlr
可能简单的forEach循环添加到相应的列表会是更好的选择。 - Ryuzaki L
2个回答

6

若要实现类型安全的解决方案,您需要定义一个包含所需结果的类。此类型可能还提供了添加另一个 Customer 或部分结果所需的必要方法:

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

然后,您可以像这样收集所有结果:

CustomerProperties all = customers.stream()
    .collect(CustomerProperties::new, CustomerProperties::add, CustomerProperties::add);

3
你可以这样创建一个方法:
public <T> List<T> getByFieldName(List<Customer> customerList, Function<Customer, T> field){
    return customerList.stream()
            .map(field)
            .collect(Collectors.toList());
}

那么只需使用要求的字段调用您的方法:
List<Integer> ids = getByFieldName(customerList, Customer::getId);
List<String> countries = getByFieldName(customerList, Customer::getCountry);
List<Integer> customerIds = getByFieldName(customerList, Customer::getCustomerId);
//...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接