Avendo una lista di stringhe, ho bisogno di costruire una lista di oggetti che sono effettivamente coppie (string, its position in the list)
. Attualmente ho un tale codice utilizzando le raccolte di google:Come mappare gli elementi della lista ai loro indici usando i flussi Java 8?
public Robots(List<String> names) {
ImmutableList.Builder<Robot> builder = ImmutableList.builder();
for (int i = 0; i < names.size(); i++) {
builder.add(new Robot(i, names.get(i)));
}
this.list = builder.build();
}
Mi piacerebbe farlo utilizzando Java 8 stream. Se non ci fosse alcun indice, ho potuto solo fare:
public Robots(List<String> names) {
this.list = names.stream()
.map(Robot::new) // no index here
.collect(collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList
));
}
Per ottenere l'indice, che avrei dovuto fare qualcosa di simile:
public Robots(List<String> names) {
AtomicInteger integer = new AtomicInteger(0);
this.list = names.stream()
.map(string -> new Robot(integer.getAndIncrement(), string))
.collect(collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList
));
}
Tuttavia, la documentazione dice che la funzione di mappatura dovrebbe essere senza stato , ma lo AtomicInteger
è effettivamente il suo stato.
C'è un modo per mappare gli elementi del flusso sequenziale alle loro posizioni nello stream?
Se stavo usando 'next()' da ' Iterator' nella funzione di mappatura, sarebbe stato. 'zipWithIndex' sembra interessante - non usa la lista direttamente, quindi funzionerà con qualsiasi flusso. Grazie! –
@JaroslawPawlak Sì, è vero. E sì se l'elenco sottostante è un 'LinkedList' per esempio; otterrai cattive prestazioni. Il 'zipWithIndex' restituisce un flusso con indici' Long'; se hai veramente bisogno di 'Integer', puoi usare il metodo zip fornendo un' IntStream' (potenzialmente) infinito :-) –