3 votes

Est-il possible de joindre deux flux Java 8 ?

Je me demandais si je pouvais rejoindre deux pré-trié (en un seul passage). Par exemple, si j'ai les classes Java suivantes :

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;
}

Et j'ai des flux pré-triés, comme dans :

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();

Je voulais appliquer addCar() à Johnny avec la "Mazda" et la "Fiat". Il n'y a pas de voiture pour Anne, et Marie n'est pas une cliente.

Est-il possible de joindre les deux flux avec un seul passage sur les flux ?

J'ai vu des solutions où un flux est parcouru plusieurs fois, mais comme ils sont précommandés, je suppose qu'il pourrait y avoir une chance de le faire en un seul passage.

EDITAR : Le résultat attendu de l'opération serait d'appeler addCar() deux fois pour "Johnny" : une fois avec la "Mazda", une fois avec la "Fiat".

3voto

Bananon Points 2034

Je crains qu'il ne soit pas possible de résoudre efficacement cette tâche en utilisant l'API Stream. Mais vous pouvez toujours le faire en utilisant les itérateurs.

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);
    }
}

1voto

nullpointer Points 1135

Un précalcul peut aider. Quelque chose comme

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));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X