Ho un elenco di oggetti con molti campi duplicati e alcuni che devono essere uniti. Voglio ridurlo a un elenco di oggetti unici utilizzando solo Java 8 Stream (so come farlo tramite old-skool significa, ma questo è un esperimento.)Raggruppa e riduce l'elenco degli oggetti
Questo è quello che ho adesso. Non mi piace molto perché la creazione di mappe sembra estranea e la collezione values () è una vista della mappa di supporto, e devi metterla in un nuovo ArrayList<>(...)
per ottenere una collezione più specifica. Esiste un approccio migliore, magari utilizzando le operazioni di riduzione più generali?
@Test
public void reduce() {
Collection<Foo> foos = Stream.of("foo", "bar", "baz")
.flatMap(this::getfoos)
.collect(Collectors.toMap(f -> f.name, f -> f, (l, r) -> {
l.ids.addAll(r.ids);
return l;
})).values();
assertEquals(3, foos.size());
foos.forEach(f -> assertEquals(10, f.ids.size()));
}
private Stream<Foo> getfoos(String n) {
return IntStream.range(0,10).mapToObj(i -> new Foo(n, i));
}
public static class Foo {
private String name;
private List<Integer> ids = new ArrayList<>();
public Foo(String n, int i) {
name = n;
ids.add(i);
}
}
È possibile implementare questo "vecchio skool" (convenzionalmente, senza lambda/flussi) senza utilizzare una mappa intermedia? Penso che, dal momento che i duplicati potenzialmente possono verificarsi ovunque nell'input, devono essere tutti memorizzati in un buffer da qualche parte fino a quando tutti gli input sono stati elaborati. –