1. Inovații în Java 8: Programare funcțională

Odată cu lansarea Java 8, limbajul a câștigat un suport puternic pentru programarea funcțională . Ați putea spune chiar că a câștigat suport mult așteptat pentru programarea funcțională. Codarea a devenit mai rapidă, deși codul era mai greu de citit 🙂

Înainte de a învăța programarea funcțională în Java, vă recomandăm să înțelegeți bine trei lucruri:

  1. POO, moștenire și interfețe ( nivelurile 1-2 în căutarea Java Core ).
  2. Implementări implicite ale metodei într-o interfață .
  3. Clase interioare și anonime .

Vestea bună este că nu trebuie să știți toate acestea pentru a utiliza multe dintre caracteristicile programării funcționale în Java. Vestea proastă este că va fi dificil de înțeles exact cum este aranjat totul și cum funcționează totul fără a ști despre clasele interioare anonime.

În lecțiile următoare, ne vom concentra asupra cât de ușor și simplu este să utilizați caracteristicile de programare funcțională ale Java, fără a înțelege profund modul în care funcționează.

Este nevoie de luni pentru a înțelege toate nuanțele programării funcționale în Java. Puteți învăța să citiți un astfel de cod în câteva ore. Așa că vă sugerăm să începeți cu puțin. Chiar dacă este cu fluxuri I/O.


2. Fluxuri I/O: conducte de flux

Îți amintești că cândva ai aflat despre fluxurile I/O: InputStream, OutputStream, Reader, Writeretc.?

Au existat clase de fluxuri care citesc date din surse de date , cum ar fi FileInputSteam, și au existat fluxuri de date intermediare care citesc date din alte fluxuri, cum ar fi InputStreamReaderși BufferedReader.

Aceste fluxuri ar putea fi organizate în conducte de procesare a datelor. De exemplu, așa:

FileInputStream input = new FileInputStream("c:\\readme.txt");
InputStreamReader reader = new InputStreamReader(input);
BufferedReader buff = new BufferedReader(reader);

String text = buff.readLine();

Este important să rețineți că în primele câteva linii de cod, doar construim un lanț de Streamobiecte. Datele nu au trecut încă prin conductă.

Dar, de îndată ce numim buff.readLine()metoda, se va întâmpla următoarele:

  1. Obiectul BufferedReaderapelează read()metoda pe InputStreamReaderobiect
  2. Obiectul InputStreamReaderapelează read()metoda pe FileInputStreamobiect
  3. Obiectul FileInputStreamîncepe să citească datele din fișier

Cu alte cuvinte, nu există nicio mișcare a datelor de-a lungul conductei de flux până când începem să apelăm metode precum read()sau readLine(). Simpla construcție a conductei de flux nu conduce date prin ea. Fluxurile în sine nu stochează date. Citesc doar de la alții.

Colecții și fluxuri

Începând cu Java 8, a devenit posibil să obțineți un flux pentru a citi date din colecții (și nu numai din acestea). Dar acesta nu este cel mai interesant lucru. De fapt, a devenit posibil să se construiască ușor și simplu lanțuri complexe de fluxuri de date. Și făcând acest lucru, codul care anterior avea 5-10 linii putea fi acum scris în 1-2 rânduri.

Exemplu de găsire a celui mai lung șir dintr-o listă de șiruri:

Găsirea celui mai lung șir
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max((s1, s2)-> s1.length()-s2.length()).get();
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();
Optional<String> optional = stream.max((s1, s2)-> s1.length()-s2.length());
String max = optional.get();

3. Streaminterfață

Suportul extins al Java 8 pentru fluxuri este implementat folosind interfața Stream<T>, unde Teste un parametru de tip care indică tipul de date care sunt transmise în flux. Cu alte cuvinte, un flux este complet independent de tipul de date pe care îl transmite.

Pentru a obține un obiect flux dintr-o colecție , trebuie doar să apelați stream()metoda acestuia. Codul arată cam așa:

Stream<Type> name = collection.stream();
Obținerea unui flux dintr-o colecție

În acest caz, colecția va fi considerată sursa de date a fluxului, iar obiectul Stream<Type>va fi un instrument pentru obținerea datelor din colecție sub forma unui flux de date.

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();

Apropo, puteți obține un flux nu numai din colecții, ci și din matrice . Pentru a face acest lucru, trebuie să utilizați metoda. De exemplu:Arrays.stream()

Stream<Type> name = Arrays.stream(array);
Obținerea unui flux dintr-o matrice

În acest caz, matricea va fi considerată sursa de date pentru fluxul numit name.

Integer[] array = {1, 2, 3};
Stream<Integer> stream = Arrays.stream(array);

Nicio dată nu este mutată atunci când Stream<Type>obiectul este creat. Pur și simplu am primit un obiect de flux pentru a începe să construim o conductă de flux.