JavaRush /Java Blog /Random-IT /API di flusso

API di flusso

Pubblicato nel gruppo Random-IT
API di flusso - 1

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.
API di flusso - 1
Con l'avvento di Java 8, l'API Stream ha consentito ai programmatori di scrivere molto più brevemente ciò che in precedenza richiedeva molte righe di codice, vale a dire semplificare il lavoro con i set di dati, in particolare, per semplificare le operazioni di filtraggio, ordinamento e altre operazioni di manipolazione dei dati. Se non disponi di operazioni intermedie, puoi e dovresti spesso fare a meno dello stream, altrimenti il ​​codice sarà più complicato che senza stream.
API di flusso - 2
Da dove dovrei iniziare esattamente? Dalla creazione di un'istanza di Stream, che si basa sulla raccolta, array o metodo di cui abbiamo bisogno e da dove verranno presi i dati di conseguenza:
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:
API di flusso - 3
  • 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")
Inoltre esistono gli operatori (essenzialmente metodi della classe Stream), che possono essere divisi in due gruppi:
  • 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.
Esempio:
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, xequivale a un elemento della raccolta per l'enumerazione (come con for each) e dopo -> indichiamo come viene filtrata la nostra raccolta e poiché si tratta di un operatore intermedio, la raccolta filtrata approfondisce il metodo , forEachche a sua volta è l'analogo terminale (finale) dell'enumerazione for each(Espressione System.out::printlnabbreviata di:, x-> System.out.println(x))che a sua volta esamina tutti gli elementi della raccolta che gli sono passati e lo visualizza)
API di flusso - 5
Punti importanti:
  • 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 =( ;
  • API di flusso - 6

    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));
Successivamente, diamo un'occhiata ad alcuni operatori intermedi:
API di flusso - 7
  • 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.functionControlla 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 funzionale Function<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 di map, vengono utilizzati per la conversione in un flusso primitivo.
Quando si lavora, ad esempio, con un array di flussi (array, elenchi e così via), li converte in un unico flusso (array, elenco e così via [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 mapsi 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)
E un altro esempio di confronto, flatMap:
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
Operatori terminalistici:
API di flusso - 8
  • 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à ( supplierfornisce nuovi oggetti (contenitori), ad esempio new ArrayList(), accumulatoraggiunge un elemento al contenitore, combinercombina 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 identityvengono presi l'oggetto e il primo elemento dello stream, viene applicata la funzione accumulatore identityil 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 iniziale identity, è il primo elemento dello stream

    Optional 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 condizione predicate:

    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 condizione predicate:

    Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
E infine vorrei esaminare alcuni metodi Collectors:
  • toList()— raccoglie gli elementi in List:

    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.

Link utili: PS: non siate timidi nel riempirci di like ^ : ^
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION