JavaRush /Java Blog /Random-IT /Flussi semplici non semplici
Oleg Savenko
Livello 41
Одесса

Flussi semplici non semplici

Pubblicato nel gruppo Random-IT
Con ogni nuova versione di Java diventa sempre più ricco. Sebbene gran parte della ricchezza risieda nelle versioni precedenti, il linguaggio ha continuato a migliorare sia nella metodologia che nell'implementazione. Le raccolte in Java non fanno eccezione. Il framework delle collezioni principali è apparso in J2SE 1.2 e ha continuato ad evolversi, subendo cambiamenti più piacevoli che deludenti. Con il rilascio di JDK 5, le raccolte sono diventate più pratiche, veloci e facili da utilizzare. Ciò ha portato al fatto che i programmatori hanno iniziato a sfruttarli più intensamente. Sono stati sviluppati alcuni modelli per lavorare con loro, che sono senza dubbio efficaci. Ma con JDK 8, le raccolte sono migliorate di nuovo, e sono migliorate grazie ai thread. Ovviamente, poiché la raccolta può essere rappresentata sotto forma di flussi, cambierà anche la metodologia per lavorare con essi. Pertanto, voglio mostrare come le soluzioni familiari e comprensibili con le raccolte diventino ancora più semplici.

Esempio 1. Non potrebbe essere più semplice

Naturalmente iniziamo con la cosa più semplice, esaminiamo tutti gli elementi della collezione e visualizziamo tutti gli elementi.
// создадим и заполним список
   List<Integer> list = new ArrayList<>();
   Collections.addAll(list, 1, 5, 6, 11, 3, 15, 7, 8);
   // а теперь
   // быстрый for по всем elementм, только для коллекций
   for (Integer i:list){
       System.out.println(i);
   }
   //но мы уже живем в JDK 8
   //а значит нужно так
   list.stream().forEach(System.out::println);
Come hai notato, c'è una nuova sintassi che, a mio parere come principiante di Java, è molto più semplice. Quindi, cosa è visibile nella nuova sintassi:
берем_список(list).превращаем_в_поток(stream).перебираем_все_элементы(forEach)(тут_интуитивно_понятно)
System.out::println— un collegamento a un metodo statico che restituisce una stringa alla console Invece di un collegamento a un metodo statico, puoi utilizzare una voce leggermente diversa e meno chiara:
list.stream().forEach(i -> System.out.println(i));
Questa voce utilizza espressioni lambda. E sì, per imparare a lavorare con i flussi, dovrai imparare le espressioni lambda: sono meravigliose. Inoltre, non mostrerò come lavorare con le raccolte utilizzando solo i flussi, confidando nel fatto che durante il corso hai acquisito familiarità con i metodi tradizionali.

Esempio 2. Trova i valori pari nell'elenco e visualizzali nella console

list.stream().filter(i -> i%2==0).forEach(System.out::println);
L'intero problema è stato risolto in una riga. Spero che ti piaccia lavorare in una riga. Utilizzando il metodo, filterabbiamo filtrato il flusso e inviato ciò che era rimasto alla console. Il filtro è una cosa molto potente che può aiutare nei casi più inaspettati. Diventiamo creativi e cambiamo le condizioni del problema. Ad esempio, dobbiamo contare quanti numeri pari sono presenti nell'elenco:
long count = list.stream().filter(i -> i%2==0).count();
E ancora in una riga. In qualche modo tutto sembra semplice. Nel filtro, abbiamo utilizzato un'espressione lambda, inserendo quindi solo i numeri pari nel nuovo flusso, e quindi applicata a new stream count, che contava quanti elementi sono presenti nel nuovo flusso.

Esempio 3. Contiamo quante parole nell'elenco sono lunghe 5 caratteri

Abbiamo giocato con i numeri interi, ora giochiamo con le parole.
List<String> list = new ArrayList<>();
Collections.addAll(list, "разые", "слова", "интересные", "And", "Not", "Very");

System.out.println(list.stream().filter(w -> w.length() == 5).count());
Abbiamo usato di nuovo il filtro. Nel filtro, utilizzando un'espressione lambda, è stato visualizzato un nuovo flusso e quindi, comprensibilmente, countho calcolato quanti elementi c'erano nel nuovo flusso.

Esempio 4. Stampa parole univoche

Un compito familiare quando leggiamo molte parole diverse in una raccolta da un file e ora abbiamo solo bisogno di parole uniche.
List<String> list = new ArrayList<>();
Collections.addAll(list, "Vasya", "Таня", "Olya", "Vasya", "Olya", "Сергей");

list.stream().distinct().forEach(System.out::println);
L'azione principale è stata eseguita sullo stream utilizzando distinct. Successivamente, suggerisco di dare un'occhiata ad alcune delle nostre attività del corso utilizzando i thread

Esempio 5. Parole lunghe

Al 9 ° livello di Java Core, nella lezione 11 c'è un problema interessante, in esso devi scrivere parole separate da virgole nel File2, la cui lunghezza è rigorosamente maggiore di 6. Non importa che tipo di giardino stai recintando, Propongo la seguente soluzione:
  1. Dal file sorgente leggiamo tutte le parole nell'elenco.

  2. Quindi eseguiamo la riga seguente

    Optional<String> rezult = list.stream()
    				.filter(w->w.length()>6)
    				.reduce((w1,w2)->w1+", "+w2);
  3. result.get()scrivere in un file.

Ecco una soluzione interessante utilizzando i thread. Il filtro ha filtrato e, utilizzando reduce e un'espressione regolare, è stata generata la stringa richiesta.

Esempio 6. Parole con numeri

Scrivi tutte le parole che contengono numeri, ad esempio a1 o abc3d, separate da uno spazio in File2. Anche questa è una condizione del nostro libro dei problemi, come hai intuito, la soluzione è semplice.
Optional<String> rezult = list.stream()
				.filter(w->w.matches(".*?\\d+.*?"))
				.reduce((w1,w2)->w1+" "+w2);
Abbiamo filtrato il flusso utilizzando un'espressione regolare, quindi reduce e un'espressione lambda. Questo ha molto in comune con il compito precedente.

Esempio 7. Selezione dei numeri

L'intero compito suona così:
  • Leggere 2 nomi di file dalla console.
  • Emetti nel secondo file tutti i numeri presenti nel primo file.
  • I numeri sono separati da spazi.
  • Chiudi i flussi.
Per l'attività principale, ovvero scrivere numeri in una stringa separata da spazi, per scrivere ulteriormente su un file, suggerisco di utilizzare uno stream, sarà simile a questo:
Optional<String> rezult = list.stream().filter(w->w.matches("\\d+"))
				.reduce((w1,w2)->w1+" "+w2);
System.out.println(rezult.get());
Utilizzando i thread, il problema viene risolto in modo molto semplice. Ma ecco, confronta tu stesso questa soluzione con le due precedenti. Concludendo l'articolo, voglio confessarvi: ragazzi, ho barato quando ho selezionato gli esempi. Il fatto è che ho scelto gli esempi più semplici per mostrarti un argomento sconosciuto utilizzando problemi familiari. Naturalmente, i thread vengono utilizzati sia per compiti semplici che per compiti più complessi. Ma come ha sottolineato Horstman nel suo libro, “i flussi di dati funzionano secondo il principio “cosa, non come fare””, il che significa che molti compiti precedentemente complessi possono diventare più semplici. Non so voi, ma a me i flow piacevano, spero di non avervi scoraggiato dall’impararli. E lasciatemi spiegare un'altra cosa:
  1. Non ho intenzione di insegnare al lettore come utilizzare i flussi nelle raccolte; non sono un insegnante così esperto. Volevo mostrarti che i thread sono semplici e molto interessanti! In generale, questa è una necessità.
  2. Più capisco i flussi, più vedo problemi in cui risolvono tutti i problemi del libro di testo, il che significa che i flussi non sono stati inventati invano.
  3. Non solo è facile lavorare con i flussi, ma presentano anche un vantaggio importante: quando si lavora con grandi quantità di dati, i flussi sono spesso più produttivi.
PS . Stavo scherzando su TUTTI I PROBLEMI. Consigliato: libreria Java professionale. Volume 2 Strumenti di programmazione avanzati. Kay Horstmann. Ho la decima edizione.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION