我有一个汽车列表
List<Car> cars = ...;
汽车有Owner
且Owner
有ContactNumber
汽车
public class Car {
private Owner owner;
public Owner getOwner(){
return owner;
}
}
所有者
public class Owner {
private ContactNumber contactNumber;
public ContactNumber getContactNumber() {
return contactNumber;
}
}
我知道我可以使用
对车主进行分组Map<Owner, List<Car>> groupByOwner = cars.stream().collect(groupingBy(Car::getOwner));
有没有办法我可以使用流分组Owner
和ContactNumber
知道一个ContactNumber
只能与一个Owner
相关联?
如果多个ContactNumber
可以共享Owner
,我该怎么做呢?
即创建以下地图:
Map<Owner, List<Car>> groupByOwner = cars.stream().collect(groupingBy(Car::getOwner))
Map<ContactNumber, Map<Owner, List<Car>>> groupByContactNumberAndOwner = groupByOwner...
答案 0 :(得分:3)
如果你知道
一个
相关联ContactNumber
只能与一个Owner
然后,您不需要内部地图。只需直接按ContactNumber
分组:
Map<ContactNumber, List<Car>> groupByOwnerContactNumber = cars.stream()
.collect(Collectors.groupingBy(c -> c.getOwner().getContactNumber()));
不要害怕使用lambda表达式;)
修改强>
根据问题的第二部分:
如果多个
可以共享ContactNumber
Owners
您可以使用接受下游收集器的Collectors.groupingBy
的重载版本来执行嵌套分组:
Map<ContactNumber, Map<Owner, List<Car>>> groupByOwnerAndContactNumber =
cars.stream().collect(Collectors.groupingBy(
c -> c.getOwner().getContactNumber(),
Collectors.groupingBy(Car::getOwner)));
另一种方法是按复合键(ContactNumber, Owner)
进行分组。您可以通过将密钥设为List<Object>
:
Map<List<Object>, List<Car>> groupByCompundOwnerContactNumber =
cars.stream().collect(Collectors.groupingBy(
c -> Arrays.asList(c.getOwner().getContactNumber(), c.getOwner())));
这不需要嵌套分组操作。
注意:如果您使用的是Java 9,则可以使用List.of
代替Arrays.asList
。
答案 1 :(得分:1)
要获得我正在寻找的Map<ContactNumber, Map<Owner, List<Car>>>
收藏品,我必须这样做:
Map<ContactNumber, Map<Owner, List<Car>>> response = cars.stream()
.collect(groupingBy(c -> c.getOwner().getContactNumber(), groupingBy(Car::getOwner)));
使用重载收集器
groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)
您将使用的地方:
groupingBy(
list element -> root key of the map,
groupingBy(list element -> second level key of the map)
);