Primitive Type Streams i Java 8

1. Introduksjon

Stream API var en av nøkkelfunksjonene som ble lagt til i Java 8.

Kort fortalt lar API oss behandle samlinger og andre sekvenser av elementer - praktisk og mer effektivt - ved å tilby et deklarativt API.

2. Primitive bekker

Strømmer fungerer primært med samlinger av objekter og ikke primitive typer.

Heldigvis å gi en måte å jobbe med de tre mest brukte primitive typene på - int, lang og dobbelt - standardbiblioteket inkluderer tre primitive spesialiserte implementeringer: IntStream, LongStream, og DoubleStream.

Primitive strømmer er begrenset, hovedsakelig på grunn av boksing overhead, og fordi det ikke er så nyttig å lage spesialiserte strømmer for andre primitiver i mange tilfeller.

3. Aritmetiske operasjoner

La oss starte med noen interessante metoder for mye brukte regneoperasjoner som min, maks, sum, og gjennomsnitt:

int [] heltall = ny int [] {20, 98, 12, 7, 35}; int min = Arrays.stream (heltall) .min () .getAsInt (); // returnerer 7

La oss nå gå gjennom kodebiten ovenfor for å forstå hva som skjer.

Vi skapte vår IntStream ved bruk av java.util.Arrays.stream (int []) og brukte deretter min () metode for å få det laveste heltallet som java.util.OptionalInt og til slutt ringte getAsInt () å få int verdi.

En annen måte å lage en IntStream bruker IntStream.of (int ...). De maks () metoden vil returnere det største heltallet:

int max = IntStream.of (20, 98, 12, 7, 35) .max () .getAsInt (); // returnerer 98

Neste - for å få summen av heltall kaller vi bare sum() metode og vi trenger ikke å bruke getAsInt () siden det allerede returnerer resultatet som et int verdi:

int sum = IntStream.of (20, 98, 12, 7, 35) .sum (); // returnerer 172

Vi påkaller gjennomsnitt() metode for å få gjennomsnittet av heltallverdier, og som vi kan se, bør vi bruke getAsDouble () da den returnerer en verdi av typen dobbelt.

dobbel avg = IntStream.of (20, 98, 12, 7, 35). gjennomsnittlig () .getAsDouble (); // returnerer 34.4

4. Rekkevidde

Vi kan også lage en IntStream basert på en rekkevidde:

int sum = IntStream.range (1, 10) .sum (); // returnerer 45 int sum = IntStream.rangeClosed (1, 10) .sum (); // returnerer 55

Som kodebiten ovenfor viser, er det to måter å lage et utvalg av heltallverdier område() og rekkeviddeLukket ().

Forskjellen er at slutten av område() er eksklusiv mens det er inkluderende i rekkeviddeLukket ().

Områdemetoder er bare tilgjengelige for IntStream og LongStream.

Vi kan bruke rekkevidde som en fancy form av en for-hver løkke:

IntStream.rangeClosed (1, 5) .forEach (System.out :: println);

Det som er bra å bruke dem som erstatning for hver løkke, er at vi også kan dra nytte av den parallelle kjøringen:

IntStream.rangeClosed (1, 5) .parallel () .forEach (System.out :: println);

Så nyttig som disse fancy løkkene er, er det fortsatt bedre å bruke de tradisjonelle forløkkene i stedet for den funksjonelle for enkle iterasjoner på grunn av enkelhet, lesbarhet og ytelse i noen tilfeller.

5. Boksing og unboksing

Det er tider når vi trenger å konvertere primitive verdier til deres innpakningsekvivalenter.

I slike tilfeller kan vi bruke innrammet () metode:

Liste evenInts = IntStream.rangeClosed (1, 10) .filter (i -> i% 2 == 0) .boxed () .collect (Collectors.toList ());

Vi kan også konvertere fra wrapper class stream til primitive stream:

// returnerer 78 int sum = Arrays.asList (33,45) .stream () .mapToInt (i -> i) .sum ();

Vi kan alltid bruke mapToXxx og flatMapToXxx metoder for å skape primitive strømmer.

6. Konklusjon

Java Streams er et veldig kraftig tillegg til språket. Vi har knapt skrapet overflaten av primitive strømmer her, men som du allerede kan bruke dem til å være produktive.

Og som alltid kan kodeeksempler finnes på GitHub.