流按确定对象的总和分组

时间:2018-07-02 11:01:32

标签: dictionary java-8 java-stream treemap collectors

我有一个像这样的Request类:

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

我想将请求分组为Map | Integer,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 :(得分:2)

我认为您需要两个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]}

答案 1 :(得分:0)

这是另一种方式,

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]}