Группировка потоков по сумме определенных объектов - PullRequest
0 голосов
/ 02 июля 2018

У меня есть класс запроса, подобный этому:

public class Request 
{
String name,destName;
int nSeats;
//Example : requestOne,Paris,3
...
}

Я хочу сгруппировать запрос в Map | Integer, List of String | где ключи - это сумма запроса с тем же именем DestName, а значения - имена адресатов.

Вот мой код:

public TreeMap<Integer, List<String>> destinationsPerNSeats() {
return requests.
stream().
collect(Collectors.groupingBy(Request::getnSeats, TreeMap::new, 
Collectors.mapping(Request::getDestName, Collectors.toList()))).
}

Ввод:

TreeMap<Integer, List<String>> map = mgr.destinationsPerNSeats();
print(map);

Вывод: {4 = [Париж], 3 = [Лондон, Берлин, Берлин], 2 = [Париж]}

Ожидаемый результат: {6 = [Берлин, Париж], 3 = [Лондон]}

Как я могу решить это? Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Вот еще один способ сделать это,

Map<Integer, List<String>> result = requests.stream()
        .collect(Collectors.collectingAndThen(
                Collectors.groupingBy(Request::getDestName, Collectors.summingInt(Request::getnSeats)),
                map -> map.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue,
                        Collectors.mapping(Map.Entry::getKey, Collectors.toList())))));

Сначала создайте Map по имени получателя и общее количество запросов к этому получателю. Затем используйте это Map для построения данных, которые вы хотите. Значение предыдущей карты становится ключом новой, а ключ предыдущей карты становится значением новой. Наконец мы собираем их в List.

А вот вывод :

{3=[London], 6=[Berlin, Paris]}
0 голосов
/ 02 июля 2018

Я думаю, вам нужны два Stream конвейера. Первый сгруппирует места назначения и суммирует общее количество мест для каждого имени места назначения, а второй сгруппирует имена места назначения по количеству мест:

public TreeMap<Integer, List<String>> destinationsPerNSeats() {
    return
        requests.stream()
                .collect(Collectors.groupingBy(Request::getDestName, 
                                               Collectors.summingInt(Request::getnSeats)))
                .entrySet()
                .stream()
                .collect(Collectors.groupingBy(Map.Entry::getValue,
                                               TreeMap::new,
                                               Collectors.mapping(Map.Entry::getKey,Collectors.toList())));
}

Тестирование вашего кода со следующим вводом:

List<Request> requests = new ArrayList<> ();
requests.add (new Request("John","Paris",4));
requests.add (new Request("Ben","London",3));
requests.add (new Request("Dan","Berlin",3));
requests.add (new Request("Sara","Berlin",3));
requests.add (new Request("Jenn","Paris",2));

производит Map:

{3=[London], 6=[Berlin, Paris]}
...