Разбить список объектов на несколько списков значений полей, используя потоки Java - PullRequest
2 голосов
/ 17 февраля 2020

Допустим, у меня есть такой объект:

public class Customer {

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

и у меня есть List<Customer>. Я хотел бы разделить такой список на потоки Java, чтобы получить список идентификаторов List<Integer>, стран List<String>, customerIds List<Integer> et c.

Я знаю, что мог бы сделать это так же просто, как сделать 6 потоков, таких как:

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

, но делать это так часто, что у меня есть поля, кажется довольно скучным. Я думал о собственном Collector, но не смог придумать что-нибудь полезное, что было бы одновременно аккуратно и эффективно.

Ответы [ 2 ]

4 голосов
/ 17 февраля 2020

Для безопасного типа решения вам нужно определить класс, содержащий желаемые результаты. Этот тип также может предоставлять необходимые методы для добавления другого 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);
2 голосов
/ 17 февраля 2020

Вы можете создать метод следующим образом:

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);
//...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...