Cos'è l'API Stream?
L'API Stream è un nuovo modo di lavorare con le strutture dati in uno stile funzionale. Un'API Stream (una descrizione dei modi in cui un programma per computer può comunicare con un altro programma) è, essenzialmente, un flusso di dati. Il termine stesso "thread" è piuttosto vago nella programmazione in generale e in Java in particolare.List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
list.add("Four");
list.add("Five");
list.add("Six");
list.add("Seven");
list.add("Eight");
list.add("Nine");
list.add("Ten");
Stream stream = list.stream();
Come accennato in precedenza, l'API Stream consente di ridurre il numero di righe di codice. Esempio con un flusso:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
Esempio senza filo:
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
int count = 0;
for (int x : arr) {
if (x >= 90) continue;
x += 10;
count++;
if (count > 3) break;
System.out.print(x);
}
Possibili modi per creare uno stream:
- Flusso vuoto:
Stream.empty()
- Trasmetti dall'elenco:
list.stream()
- Stream dalla mappa:
map.entrySet().stream()
- Stream dall'array:
Arrays.stream(array)
- Stream dagli elementi specificati:
Stream.of("1", "2", "3")
- Intermedio (chiamato anche “pigro”): elabora gli elementi in arrivo e restituisce il flusso. Possono esserci molti operatori intermedi nella catena di lavorazione degli elementi.
- Terminale ("terminale", chiamato anche "desideroso"): elabora gli elementi e termina il flusso, quindi può esserci un solo operatore terminale nella catena.
1.List<String> list = new ArrayList<String>();
2.list.add("One");
…
11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
Cosa sta succedendo qui:
- 1 - creare una lista
list
; - 2-11 - riempilo con i dati del test;
- 12 - creare un oggetto
Stream
; - 13 - metodo
filter
(filtro) - operatore intermedio,x
equivale a un elemento della raccolta per l'enumerazione (come confor each
) e dopo -> indichiamo come viene filtrata la nostra raccolta e poiché si tratta di un operatore intermedio, la raccolta filtrata approfondisce il metodo ,forEach
che a sua volta è l'analogo terminale (finale) dell'enumerazionefor each
(EspressioneSystem.out::println
abbreviata di:,x-> System.out.println(x))
che a sua volta esamina tutti gli elementi della raccolta che gli sono passati e lo visualizza)
- L'elaborazione non inizierà finché non verrà chiamato l'operatore del terminale.
list.stream().filter(s -> s > 5)
(non prenderà un singolo elemento dalla lista); - Un'istanza di uno stream non può essere utilizzata più di una volta =( ;
Pertanto, ogni volta che è nuovo:
list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
list.stream().forEach(x -> System.out.println(x));
Possono esserci molti operatori intermedi chiamati su un flusso, mentre esiste un solo operatore terminale:
stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
filter(Predicate predicate)
filtra il flusso, passando solo quegli elementi che superano la condizione (Predicate è un'interfaccia funzionale integrata aggiunta al pacchetto in Java SE 8.java.util.function
Controlla il valore per " true " e " false ");map(Function mapper)
permette di creare una funzione con la quale cambieremo ogni elemento e lo salteremo ulteriormente (L'interfaccia funzionaleFunction<T,R>
rappresenta la funzione di transizione da un oggetto di tipo T ad un oggetto di tipo R)flatMap(Function<T, Stream<R>> mapper)
- come nel caso dimap
, vengono utilizzati per la conversione in un flusso primitivo.
[stream1,stream2,stream3,stream4] => stream
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.flatMap(Arrays::stream).distinct() //aligns each generated thread into a single thread
.collect(Collectors.toList()).forEach(System.out::println);
Mentre map
si converte in un elenco di thread (più precisamente <Stream>
thread) [stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4)
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.map(Arrays::stream).distinct() //Make the array into a separate thread
.collect(Collectors.toList()).forEach(System.out::println);
Un'altra differenza rispetto a map
, puoi convertire un elemento in zero, uno o molti altri. Per convertire un elemento in zero elementi, è necessario restituire null
, o un flusso vuoto. Per convertire in un elemento, è necessario restituire un flusso da un elemento, ad esempio tramite Stream.of(x)
. Per restituire più elementi, puoi creare uno stream con questi elementi in qualsiasi modo. Lo stesso metodo flatMap, ma per Double, Integer e Long:
- flatMapToDouble(mappatore di funzioni)
- flatMapToInt(mappatore di funzioni)
- flatMapToLong(mappatore di funzioni)
Stream.of(2, 3, 0, 1, 3)
.flatMapToInt(x -> IntStream.range(0, x))
.forEach(System.out::print);// 010120012
-
IntStream.range(0,x) – restituisce elementi da 0 (incluso) a x (non incluso) nello stream;
carta geografica:
Stream.of(2, 3, 0, 1, 3) .map(x -> IntStream.range(0, x)) .forEach(System.out::print);//list of streams (streams);
-
limit(long maxSize) – limita il flusso in base al numero di elementi:
stream.limit(5).forEach(x -> System.out.println(x));
-
skip(long n) – salta n elementi:
stream.skip(3).forEach(x -> System.out.println(x));
-
smistato()
- sorted(Comparator comparator) – ordina il flusso (ordinando come TreeMap):
stream.sorted().forEach(x -> System.out.println(x));
-
distinti() — controlla il flusso per l'unicità degli elementi (rimuove le ripetizioni degli elementi);
-
dropWhile (predicato predicato) - salta gli elementi che soddisfano la condizione (apparso in Java 9, l'interfaccia funzionale Predicate<T> controlla se una determinata condizione è soddisfatta. Se è soddisfatta, viene restituito true. L'espressione lambda accetta un oggetto di digitare T come parametro:
Predicate<Integer> isPositive = x -> x > 0; System.out.println(isPositive.test(3)); // true System.out.println(isPositive.test(-9)); // false
-
forEach(Consumer action) – analogo di for Each (Consumer<T> esegue alcune azioni su un oggetto di tipo T, senza restituire nulla);
-
count() – restituisce il numero di elementi dello stream:
System.out.println(stream.count());
-
Collect(Collector Collector) – metodo raccoglie tutti gli elementi in un elenco, set o altra raccolta, raggruppa gli elementi secondo alcuni criteri, combina tutto in una stringa, ecc.:
List<String> list = Stream.of(“One”, “Two”, “Three”).collect(Collectors.toList());
-
collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
— uguale a ,collect(collector)
solo i parametri sono suddivisi per comodità (supplier
fornisce nuovi oggetti (contenitori), ad esempionew ArrayList()
,accumulator
aggiunge un elemento al contenitore,combiner
combina insieme parti dello stream); -
reduce(T identità, accumulatore BinaryOperator) - converte tutti gli elementi dello stream in un oggetto (calcola la somma di tutti gli elementi o trova l'elemento minimo), prima
identity
vengono presi l'oggetto e il primo elemento dello stream, viene applicata la funzioneaccumulator
eidentity
il suo risultato diventa. Poi tutto continua per i restanti elementi.int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
-
reduce(BinaryOperator accumulator)
— lo stesso metodo di cui sopra ma manca quello inizialeidentity
, è il primo elemento dello streamOptional min(Comparator comparator)
Opzionale max(Comparatore comparatore) cerca l'elemento minimo/massimo in base al comparatore passato; -
findFirst()
– estrae il primo elemento dello stream:Stream.of(1, 2, 3, 4, 9).findFirst();
-
allMatch(Predicate predicate)
— restituisce vero se tutti gli elementi del flusso soddisfano la condizione. Se viene riscontrato un elemento per il quale il risultato della chiamata alla funzione predicato è false , l'operatore interrompe la scansione degli elementi e restituisce false :Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
-
anyMatch(Predicate predicate)
— restituirà vero se almeno un elemento dello stream soddisfa la condizionepredicate
:Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
-
noneMatch(Predicate predicate)
— restituirà vero se, dopo aver attraversato tutti gli elementi dello stream, nessuno di essi ha soddisfatto la condizionepredicate
:Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Collectors
:
-
toList()
— raccoglie gli elementi inList
:List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
-
toSet()
— raccoglie gli elementi in un insieme:Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
-
counting()
— Conta il numero di elementi:Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
-
joining()
-
joining(CharSequence delimiter)
-
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
— raccoglie gli elementi in un'unica riga. Inoltre, puoi specificare un separatore, nonché un prefisso e un suffisso per l'intera sequenza:String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining()); System.out.println(a); // super String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-")); System.out.println(b); // s-u-p-e-r String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]")); System.out.println(c); // [ s -> u -> p -> e -> r ]
-
summingInt(ToIntFunction mapper)
-
summingLong(ToLongFunction mapper)
-
summingDouble(ToDoubleFunction mapper)
- un raccoglitore che converte gli oggetti in int/long/double e calcola la somma.
GO TO FULL VERSION