【问题标题】:Collect call for a Map?收集电话以获取地图?
【发布时间】:2016-05-16 00:21:57
【问题描述】:

假设我们有两个 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 Collect 调用具有多个谓词以填充对象映射?

【问题讨论】:

  • 使用Collectors.toMap(...)
  • @Andreas 当然,但这并不能纠正我在这种情况下对多个参数的理解。但是,感谢您抽出宝贵时间,我很高兴知道这个个人难题有一个无循环的解决方案,假设您的评论暗示了这一点。

标签: java call collect


【解决方案1】:

你不能用你已经在使用的语句得到你想要的,因为它产生了一个Car的列表,但是CarPlate之间没有任何联系。两者都有车牌号,但是如果您有 Car,则不允许您找出 Plate,反之亦然,无需通过您发布的那种双循环 - 或无需设置Map 将车牌号映射到车牌或汽车。但是,如果您需要Map&lt;Plate, Car&gt;,则不必设置Map&lt;String, Plate&gt;Map&lt;String, Car&gt; [假设车牌号是一个字符串],尽管无论如何该地图可能是有用的东西。

我建议先创建Map&lt;Plate, Car&gt;

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 -&gt; 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 以确保以正确的顺序执行操作。 注意:我没有测试过最后一个。我认为它可以在没有同步的情况下工作,但我不确定。

【讨论】:

  • plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD) .forEachOrdered(plate -> { Car car = new Car(plate.getNumber(), modelT() ); carList.add(car); carMap.put(plate, car); });这工作得很好,初始化了汽车数组列表,然后同时填充了地图,这比我以前做过的让两者同时进行要有效得多。谢谢你,先生!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多