Добавление к списку в потоке на карту - PullRequest
5 голосов
/ 11 апреля 2019

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

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

Я пытался найти других, кто сталкивался с подобной проблемой, используя функцию потоковой передачи Java 8,но я не могу найти никого, кто пытается добавить список в карту.

Пример;

public class Product {
    public Integer productNumber();
    public Integer locationNumber();
}

List<Product> products = ... (imagine many products in this list)

Map<Integer, List<Integer>> results = products.stream()
    .collect(Collectors.toMap(p -> p.locationNumber, p -> Arrays.asList(p.productNumber));

Кроме того, второй параметр p не может получить доступ к текущему продукту в потоке.

Из-за этого я не смог проверить, могу ли я добавить в список, когда номер местоположения совпадает с уже существующим списком.Я не верю, что смогу использовать Arrays.asList (), так как считаю его неизменным.

В конце на карте должно быть много номеров товаров в списке для каждого местоположения.Можно ли добавить целые числа в существующий список на карте?

Ответы [ 2 ]

7 голосов
/ 11 апреля 2019

Вы можете сделать это так,

Map<Integer, List<Integer>> res = products.stream()
    .collect(Collectors.groupingBy(Product::locationNumber,
        Collectors.mapping(Product::productNumber, Collectors.toList())));
1 голос
/ 11 апреля 2019

API-интерфейс для сборщиков java достаточно мощный, и для его решения есть множество полезных утилит.


public class Learn {

    static class Product {
        final Integer productNumber;
        final Integer locationNumber;

        Product(Integer productNumber, Integer locationNumber) {
            this.productNumber = productNumber;
            this.locationNumber = locationNumber;
        }

        Integer getProductNumber() {
            return productNumber;
        }

        Integer getLocationNumber() {
            return locationNumber;
        }
    }

    public static Product of(int i, int j){
        return new Product(i,j);
    }

    public static void main(String[] args) {


        List productList = Arrays.asList(of(1,1),of(2,1),of(3,1),
                of(7,2),of(8,2),of(9,2));

        Map> results = productList.stream().collect(Collectors.groupingBy(Product::getLocationNumber,
                Collectors.collectingAndThen(Collectors.toList(), pl->pl.stream().map(Product::getProductNumber).collect(Collectors.toList()))));

        System.out.println(results);
    }
}

Итак, что мы делаем здесь, так это то, что мы транслируем список продуктов и группируем поток по атрибуту местоположения, но с учетом того, что мы хотим преобразовать собранный список продуктов в список номеров продуктов.

Collectors.collectingAndThen - это именно тот метод для этого, который позволит вам указать главный коллектор toList () и функцию преобразователя, которая является ничем иным как потоком для сопоставления товара с номерами товара. В java API doc основной коллектор и трансформатор помечены как нисходящий коллектор и финишер.

Пожалуйста, ознакомьтесь с исходным кодом Collectors, чтобы получить полное представление о том, как определены все эти различные сборщики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...