1. Mga Inobasyon sa Java 8: Functional na programming

Sa paglabas ng Java 8, nakakuha ang wika ng malakas na suporta para sa functional programming . Maaari mo ring sabihin na nakakuha ito ng pinakahihintay na suporta para sa functional programming. Naging mas mabilis ang coding, bagama't mas mahirap basahin ang code 🙂

Bago matutunan ang functional programming sa Java, inirerekomenda namin na maunawaan mo nang mabuti ang tatlong bagay:

  1. OOP, inheritance at mga interface ( Level 1-2 sa Java Core quest ).
  2. Default na paraan ng pagpapatupad sa isang interface .
  3. Inner at anonymous na mga klase .

Ang magandang balita ay hindi mo kailangang malaman ang lahat ng ito para magamit ang marami sa mga feature ng functional programming sa Java. Ang masamang balita ay magiging mahirap na maunawaan nang eksakto kung paano nakaayos ang lahat at kung paano gumagana ang lahat nang hindi nalalaman ang tungkol sa mga hindi kilalang panloob na klase.

Sa paparating na mga aralin, tututukan natin kung gaano kadali at kasimple ang paggamit ng mga functional programming feature ng Java, nang walang malalim na pag-unawa sa kung paano ito gumagana.

Ito ay tumatagal ng mga buwan upang maunawaan ang lahat ng mga nuances ng functional programming sa Java. Maaari mong matutunang basahin ang naturang code sa loob ng ilang oras. Kaya iminumungkahi namin na magsimula sa maliit. Kahit na ito ay may I/O stream.


2. I/O stream: stream pipelines

Naaalala mo ba na noong unang panahon ay natutunan mo ang tungkol sa mga stream ng I/O: InputStream, OutputStream, Reader, Writeratbp.?

May mga stream class na nagbabasa ng data mula sa data source , gaya ng FileInputSteam, at may intermediate data stream na nagbabasa ng data mula sa iba pang stream, gaya ng InputStreamReaderat BufferedReader.

Ang mga stream na ito ay maaaring ayusin sa mga pipeline ng pagproseso ng data. Halimbawa, tulad nito:

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

String text = buff.readLine();

Mahalagang tandaan na sa unang ilang linya ng code, gumagawa lang kami ng isang hanay ng Streammga bagay. Ang data ay hindi pa dumaan sa pipeline.

Ngunit sa sandaling tinawag namin ang buff.readLine()pamamaraan, ang mga sumusunod ay mangyayari:

  1. BufferedReaderTinatawag ng bagay ang read()pamamaraan sa InputStreamReaderbagay
  2. InputStreamReaderTinatawag ng bagay ang read()pamamaraan sa FileInputStreambagay
  3. Nagsisimula ang FileInputStreamobject sa pagbabasa ng data mula sa file

Sa madaling salita, walang paggalaw ng data sa kahabaan ng pipeline ng stream hanggang sa magsimula kaming tumawag sa mga paraan tulad ng read()o readLine(). Ang pagtatayo lamang ng pipeline ng stream ay hindi nagtutulak ng data sa pamamagitan nito. Ang mga stream mismo ay hindi nag-iimbak ng data. Nagbabasa lang sila sa iba.

Mga koleksyon at stream

Simula sa Java 8, naging posible na makakuha ng stream para magbasa ng data mula sa mga koleksyon (at hindi lamang mula sa kanila). Ngunit hindi ito ang pinakakawili-wiling bagay. Talagang naging posible na madali at simpleng bumuo ng mga kumplikadong chain ng mga stream ng data. At sa paggawa nito, ang code na dati ay tumagal ng 5-10 linya ay maaari na ngayong isulat sa 1-2 linya.

Halimbawa ng paghahanap ng pinakamahabang string sa isang listahan ng mga string:

Paghahanap ng pinakamahabang string
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

Ang pinalawig na suporta ng Java 8 para sa mga stream ay ipinapatupad gamit ang Stream<T>interface, kung saan Tay isang uri ng parameter na nagpapahiwatig ng uri ng data na ipinapasa sa stream. Sa madaling salita, ang isang stream ay ganap na independyente sa uri ng data na ipinapasa nito.

Para makakuha ng stream object mula sa isang collection , tawagan lang ang stream()method nito. Ang code ay halos ganito:

Stream<Type> name = collection.stream();
Pagkuha ng stream mula sa isang koleksyon

Sa kasong ito, ang koleksyon ay ituturing na data source ng stream, at ang Stream<Type>object ay magiging isang tool para sa pagkuha ng data mula sa koleksyon sa anyo ng data stream.

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

Sa pamamagitan ng paraan, maaari kang makakuha ng isang stream hindi lamang mula sa mga koleksyon, kundi pati na rin mula sa mga array . Upang gawin ito, kailangan mong gamitin ang pamamaraan. Halimbawa:Arrays.stream()

Stream<Type> name = Arrays.stream(array);
Pagkuha ng stream mula sa isang array

Sa kasong ito, ang array ay ituturing na data source para sa stream na tinatawag na name.

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

Walang data na inilipat kapag Stream<Type>nilikha ang bagay. Kumuha lang kami ng stream object upang simulan ang pagbuo ng stream pipeline.