1. Innovationer i Java 8: Funktionel programmering

Med udgivelsen af ​​Java 8 fik sproget kraftig støtte til funktionel programmering . Man kan endda sige, at den fik længe ventet støtte til funktionel programmering. Kodningen blev hurtigere, selvom koden var sværere at læse 🙂

Før du lærer funktionel programmering i Java, anbefaler vi, at du forstår tre ting godt:

  1. OOP, arv og grænseflader ( Niveau 1-2 i Java Core-questen ).
  2. Standardmetodeimplementeringer i en grænseflade .
  3. Indre og anonyme klasser .

Den gode nyhed er, at du ikke behøver at vide alt dette for at bruge mange af funktionerne i funktionel programmering i Java. Den dårlige nyhed er, at det bliver svært at forstå præcis, hvordan alting er indrettet, og hvordan alt fungerer uden at kende til anonyme indre klasser.

I de kommende lektioner vil vi fokusere på, hvor nemt og enkelt det er at bruge Javas funktionelle programmeringsfunktioner, uden en dyb forståelse af, hvordan det fungerer.

Det tager måneder at forstå alle nuancerne af funktionel programmering i Java. Du kan lære at læse sådan kode på et par timer. Så vi foreslår at starte i det små. Også selvom det er med I/O-streams.


2. I/O-strømme: strømrørledninger

Kan du huske, at du engang lærte om I/O-streams: InputStream, OutputStream, Reader, Writerosv.?

Der var strømklasser, der læste data fra datakilder , såsom FileInputSteam, og der var mellemliggende datastrømme, der læste data fra andre strømme, såsom InputStreamReaderog BufferedReader.

Disse strømme kunne organiseres i databehandlingspipelines. For eksempel sådan her:

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

String text = buff.readLine();

Det er vigtigt at bemærke, at i de første par linjer kode konstruerer vi kun en kæde af Streamobjekter. Dataene er ikke passeret gennem pipelinen endnu.

Men så snart vi kalder buff.readLine()metoden, vil følgende ske:

  1. Objektet BufferedReaderkalder read()metoden på InputStreamReaderobjektet
  2. Objektet InputStreamReaderkalder read()metoden på FileInputStreamobjektet
  3. Objektet FileInputStreambegynder at læse data fra filen

Med andre ord er der ingen bevægelse af data langs strømpipelinen, før vi begynder at kalde metoder som read()eller readLine(). Alene konstruktionen af ​​strømrørledningen driver ikke data igennem den. Strømmene i sig selv gemmer ikke data. De læser kun fra andre.

Samlinger og streams

Fra og med Java 8 blev det muligt at få en stream til at læse data fra samlinger (og ikke kun fra dem). Men dette er ikke det mest interessante. Det blev faktisk muligt nemt og enkelt at konstruere komplekse kæder af datastrømme. Og derved kunne koden, der tidligere tog 5-10 linjer, nu skrives i 1-2 linjer.

Eksempel på at finde den længste streng i en liste over strenge:

At finde den længste streng
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. Streamgrænseflade

Java 8's udvidede understøttelse af streams er implementeret ved hjælp af Stream<T>grænsefladen, hvor Ter en type parameter, der angiver typen af ​​data, der sendes i streamen. Med andre ord er en strøm fuldstændig uafhængig af den type data, den videregiver.

For at hente et stream-objekt fra en samling skal du blot kalde dets stream()metode. Koden ser nogenlunde sådan ud:

Stream<Type> name = collection.stream();
Hent en stream fra en samling

I dette tilfælde vil samlingen blive betragtet som streamens datakilde, og objektet Stream<Type>vil være et værktøj til at indhente data fra samlingen i form af en datastrøm.

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

Forresten kan du få en strøm ikke kun fra samlinger, men også fra arrays . For at gøre dette skal du bruge metoden. For eksempel:Arrays.stream()

Stream<Type> name = Arrays.stream(array);
Hent en stream fra et array

I dette tilfælde vil arrayet blive betragtet som datakilden for strømmen kaldet name.

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

Ingen data flyttes, når Stream<Type>objektet oprettes. Vi fik simpelthen et vandløbsobjekt for at begynde at bygge en vandløbsledning.