所以,让我们说我们有两个ArrayLists用于两个填充了东西的对象。为了便于理解,一个是车牌的ArrayList,另一个是车。
所有汽车都被分配了一个有效的车牌,然后汽车获得了车牌号......
cars.addAll(plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD)
.map(plate -> new Car(plate.getNumber(), modelT())).collect(Collectors.toList()));
然后汽车的所有者需要将他们的车牌和汽车登记在车牌和汽车的地图上。
registered = new HashMap<Plate, Car>();
for(Plate plate : plates)
if(plate.getStatus() == PLATE_GOOD)
for(Car car : cars)
if(car.getNumber() == plate.getNumber()) {
registered.put(plate, car);
break;
}
但是DMV要求没有循环并且所有者会使用收集电话。
TL; DR收集具有多个谓词的调用以填充对象地图?
答案 0 :(得分:1)
使用您已使用的语句无法获得所需内容,因为它会生成Car
列表,但Car
和Plate
之间没有关联。两者都有一个牌号,但是如果你有一个Plate
,那么这不允许你找出Car
,反之亦然,而不经过你发布的那种双循环 - 或者没有设置将板号映射到盘子或汽车的Map
。但是,如果您需要Map<Plate, Car>
,则不必设置Map<String, Plate>
或Map<String, Car>
[假设铭牌号是一个字符串],尽管该地图可能是有用的无论如何。
我建议先创建Map<Plate, Car>
:
Map<Plate, Car> carMap = plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD)
.collect(Collectors.toMap(Function.identity(), plate -> new Car(plate.getNumber(), modelT())));
这会为每个牌照创建一个新Car
并设置地图。 Collectors.toMap()
需要两个参数,这些参数是在Plate
上运行的函数。第一个将成为地图的关键,第二个将成为价值。 Function.identity()
只是意味着我们使用Plate
本身作为关键。或者您可以等效地使用plate -> plate
。
要获取汽车列表,请使用carMap.values()
。这会返回Collection
(不一定是List
),但您可以将其添加到addAll
的列表中。这不一定会以与板材相同的顺序返回汽车。如果您需要相同的订单,则可以在创建carMap
后执行此操作:
List<Car> carList = plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD)
.map(plate -> carMap.get(plate)).collect(Collectors.toList()));
我不知道有办法同时做两件事(将汽车添加到列表中,并将盘子/汽车添加到地图中),除非编写自己的代码添加到列表和地图中:
plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD)
.forEachOrdered(plate -> {
Car car = new Car(plate.getNumber(), modelT());
carList.add(car);
carMap.put(plate, car); });
需要 forEachOrdered
以确保以正确的顺序执行操作。 注意:我还没有测试过最后一个。我认为它会在没有同步的情况下工作,但我不确定。