2016-05-16 2 views
1

Итак, допустим, у нас было два массива ArrayLists для двух объектов, которые были заполнены вещами. Для простоты понимания один из них - это список лицензий, а другой - автомобилей.Соберите вызов для карты?

Всех автомобилей получают назначен действительный номерной знак, а затем автомобиль получает номер пластины в ...

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 Собирать вызов с несколькими предикатами, чтобы заполнить карту объектов?

+1

Используйте 'Collectors.toMap (...)'. – Andreas

+0

@Andreas Конечно, но это не устраняет мое понимание нескольких параметров в этом случае. Но благодарю вас за ваше время, и я рад узнать, что в этом личном затруднительном поведении отсутствует замкнутое решение, предполагающее, что ваш комментарий подразумевает это. –

ответ

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 необходим для обеспечения операция выполняется в правильном порядке. Примечание: Я не тестировал этот последний. I думаю будет работать без синхронизации, но я не уверен.

+0

plate.stream(). Filter (plate -> plate.getStatus() == PLATE_GOOD) .forEachOrdered (plate -> { Car car = новый автомобиль (plate.getNumber(), модельT()); машинаList. добавить (автомобиль); carMap.put (пластина, автомобиль);}); Это сработало отлично, инициализировало автографы, а затем засело карту в то же время, которая намного эффективнее, чем две из них, которые я делал раньше. Спасибо, сэр! <3 собирать вызовы. –

Смежные вопросы