1. Innovaties in Java 8: Functioneel programmeren

Met de release van Java 8 kreeg de taal krachtige ondersteuning voor functioneel programmeren . Je zou zelfs kunnen zeggen dat het langverwachte ondersteuning heeft gekregen voor functioneel programmeren. Coderen ging sneller, hoewel de code moeilijker te lezen was 🙂

Voordat u functioneel programmeren in Java leert , raden we u aan drie dingen goed te begrijpen:

  1. OOP, overerving en interfaces ( Niveaus 1-2 in de Java Core-zoektocht ).
  2. Standaardmethode-implementaties in een interface .
  3. Innerlijke en anonieme lessen .

Het goede nieuws is dat u dit allemaal niet hoeft te weten om veel functies van functioneel programmeren in Java te gebruiken. Het slechte nieuws is dat het moeilijk zal zijn om precies te begrijpen hoe alles is geregeld en hoe alles werkt zonder op de hoogte te zijn van anonieme innerlijke klassen.

In de komende lessen zullen we ons concentreren op hoe gemakkelijk en eenvoudig het is om de functionele programmeerfuncties van Java te gebruiken, zonder een goed begrip van hoe het werkt.

Het duurt maanden om alle nuances van functioneel programmeren in Java te begrijpen. Je kunt dergelijke code in een paar uur leren lezen. Dus we raden aan om klein te beginnen. Zelfs als het met I/O-streams is.


2. I/O-streams: stroompijplijnen

Weet je nog dat je ooit iets leerde over I/O-streams: InputStream, OutputStream, Reader, Writerenz.?

Er waren stroomklassen die gegevens uit gegevensbronnen lezen , zoals FileInputSteam, en er waren tussenliggende gegevensstromen die gegevens uit andere stromen lezen, zoals InputStreamReaderen BufferedReader.

Deze stromen kunnen worden georganiseerd in dataverwerkingspijplijnen. Bijvoorbeeld als volgt:

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

String text = buff.readLine();

Het is belangrijk op te merken dat we in de eerste paar regels code slechts een reeks Streamobjecten construeren. De gegevens zijn nog niet door de pijplijn gegaan.

Maar zodra we de buff.readLine()methode aanroepen, gebeurt het volgende:

  1. Het BufferedReaderobject roept de read()methode op het InputStreamReaderobject aan
  2. Het InputStreamReaderobject roept de read()methode op het FileInputStreamobject aan
  3. Het FileInputStreamobject begint gegevens uit het bestand te lezen

Met andere woorden, er is geen beweging van gegevens langs de stroompijplijn totdat we beginnen met het aanroepen van methoden zoals read()of readLine(). De loutere constructie van de stroompijplijn leidt er geen gegevens doorheen. De streams zelf slaan geen gegevens op. Ze lezen alleen van anderen.

Collecties en streams

Vanaf Java 8 werd het mogelijk om een ​​stream data uit collecties te laten lezen (en niet alleen uit collecties). Maar dit is niet het meest interessante. Het werd feitelijk mogelijk om eenvoudig en eenvoudig complexe ketens van datastromen aan te leggen. En daarbij kon de code die voorheen 5-10 regels in beslag nam, nu in 1-2 regels worden geschreven.

Voorbeeld van het vinden van de langste string in een lijst met strings:

De langste string vinden
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. Streaminterface

De uitgebreide ondersteuning van Java 8 voor streams wordt geïmplementeerd met behulp van de Stream<T>interface, waar Teen typeparameter is die het type gegevens aangeeft dat in de stream wordt doorgegeven. Met andere woorden, een stream is volledig onafhankelijk van het type gegevens dat wordt doorgegeven.

Om een ​​stream-object uit een verzameling te halen , roep je gewoon de stream()methode aan. De code ziet er ongeveer zo uit:

Stream<Type> name = collection.stream();
Een stream ophalen uit een verzameling

In dit geval wordt de verzameling beschouwd als de gegevensbron van de stroom en Stream<Type>is het object een hulpmiddel om gegevens uit de verzameling te verkrijgen in de vorm van een gegevensstroom.

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

Overigens kun je niet alleen een stream uit collecties halen, maar ook uit arrays . Om dit te doen, moet u de methode gebruiken . Bijvoorbeeld:Arrays.stream()

Stream<Type> name = Arrays.stream(array);
Een stream uit een array halen

In dit geval wordt de array beschouwd als de gegevensbron voor de stream met de naam name.

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

Er worden geen gegevens verplaatst wanneer het Stream<Type>object wordt gemaakt. We hebben gewoon een stream-object gekregen om te beginnen met het bouwen van een stream-pijplijn.