是否可以加入两个Java 8流?

时间:2020-03-19 18:20:17

标签: java java-8 java-stream

我想知道是否可以加入两个预排序流(一次通过)。例如,如果我具有以下Java类:

public class Person { // constructor & getters ommitted
  private String name;
  private int salary;
  private List<Car> cars;
  public void addCar(Car c) { cars.add(c); }
}

public class Car { // constructor & getters ommitted
  private String owner;
  private String brand;
}

我已经对流进行了预排序,如下所示:

Stream<Person> clients = Arrays.asList(
  new Person("Anne", 500), 
  new Person("Johnny", 340)
  ).stream();

Stream<Car> cars = Arrays.asList(
  new Car("Johnny", "Mazda"), 
  new Car("Johnny", "Fiat"), 
  new Car("Mary", "Volvo")
  ).stream();

我想用{Mazda“和” Fiat“将addCar()应用于Johnny。安妮没有车,而且玛丽不是客户。

是否可以通过一次通过将两个流加入流?

我已经看到一种解决方案,其中的一条流可以多次遍历,但是由于它们是预先订购的,所以我想可能有机会一次通过。

编辑:该操作的预期结果是为“约翰尼”调用addCar()两次:一次使用“马自达”,一次使用“菲亚特”。

2 个答案:

答案 0 :(得分:2)

恐怕无法使用Stream API有效解决此任务。但是您仍然可以使用迭代器来完成它。

public static void addCars(Stream<Person> clients, Stream<Car> cars) {
    Iterator<Person> clientsIt = clients.iterator();
    Iterator<Car> carsIt = cars.iterator();
    Person client = null;
    while (carsIt.hasNext()) {
        Car car = carsIt.next();
        while (client == null || !client.getName().equals(car.getOwner())) {
            if(!clientsIt.hasNext()) return;
            client = clientsIt.next();
        }
        client.addCar(car);
    }
}

答案 1 :(得分:1)

预计算可以提供帮助。像

Map<String, List<Car>> cars = Stream.of(
        new Car("Johnny", "Mazda"),
        new Car("Johnny", "Fiat"),
        new Car("Mary", "Volvo"))
        .collect(Collectors.groupingBy(Car::getOwner));

Stream.of(new Person("Anne", 500),
        new Person("Johnny", 340))
        .forEachOrdered(p -> cars.getOrDefault(p.getName(), 
                Collections.emptyList()).forEach(p::addCar));