1. Daftar metode Streamkelas

Kelas kasebut Streamdigawe kanggo nggawe rantai aliran data kanthi gampang. Kanggo entuk iki, Stream<T>kelas duwe metode sing ngasilake Streamobyek anyar.

Saben aliran data iki nindakake siji tumindak sing prasaja, nanging yen sampeyan gabungke menyang rantai lan nambah fungsi lambda sing menarik , sampeyan duwe mekanisme sing kuat kanggo ngasilake output sing dikarepake. Rauh sampeyan bakal weruh dhewe.

Ing ngisor iki cara kelas Stream(mung sing paling dhasar):

Metode Katrangan
Stream<T> of()
Nggawe stream saka sakumpulan obyek
Stream<T> generate()
Ngasilake stream miturut aturan sing ditemtokake
Stream<T> concat()
Concatenates loro aliran
Stream<T> filter()
Nyaring data, mung ngliwati data sing cocog karo aturan sing ditemtokake
Stream<T> distinct()
Mbusak duplikat. Ora ngliwati data sing wis ditemokake
Stream<T> sorted()
Ngurutake data
Stream<T> peek()
Nindakake tumindak ing saben unsur ing stream
Stream<T> limit(n)
Ngasilake stream sing dipotong supaya ora ngluwihi wates sing ditemtokake
Stream<T> skip(n)
Skips pisanan n unsur
Stream<R> map()
Ngonversi data saka siji jinis menyang liyane
Stream<R> flatMap()
Ngonversi data saka siji jinis menyang liyane
boolean anyMatch()
Priksa manawa ana paling ora siji unsur ing stream sing cocog karo aturan sing ditemtokake
boolean allMatch()
Priksa manawa kabeh unsur ing stream cocog karo aturan sing ditemtokake
boolean noneMatch()
Priksa manawa ora ana unsur ing stream sing cocog karo aturan sing ditemtokake
Optional<T> findFirst()
Ngasilake unsur pisanan sing ditemokake sing cocog karo aturan kasebut
Optional<T> findAny()
Ngasilake unsur apa wae ing stream sing cocog karo aturan kasebut
Optional<T> min()
Nggoleki unsur minimal ing aliran data
Optional<T> max()
Ngasilake unsur maksimum ing aliran data
long count()
Ngasilake jumlah unsur ing aliran data
R collect()
Waca kabeh data saka stream lan bali minangka koleksi

2. Operasi penengah lan terminal dening Streamkelas

Nalika sampeyan bisa ndeleng, ora kabeh cara ing tabel ndhuwur bali a Stream. Iki ana hubungane karo kasunyatan manawa metode kelas Streambisa dipérang dadi metode penengah (uga dikenal minangka non-terminal ) lan metode terminal .

Metode penengah

Cara penengah ngasilake obyek sing ngetrapake Streamantarmuka, lan bisa digandhengake.

Metode terminal

Cara terminal ngasilake nilai liyane saka Stream.

Pipa telpon metode

Mangkono, sampeyan bisa mbangun pipa stream sing kasusun saka sawetara cara penengah lan telpon cara terminal siji ing mburi. Pendekatan iki ngidini sampeyan ngetrapake logika sing rada rumit, nalika nambah keterbacaan kode.

Pipa telpon metode

Data ing aliran data ora owah. Rantai metode penengah minangka cara sing apik (deklaratif) kanggo nemtokake pipa pangolahan data sing bakal ditindakake sawise metode terminal diarani.

Ing tembung liya, yen metode terminal ora diarani, mula data ing aliran data ora diproses kanthi cara apa wae. Mung sawise cara terminal diarani, data wiwit diproses miturut aturan sing ditemtokake ing saluran pipa.

stream()
  .intemediateOperation1()
  .intemediateOperation2()
  ...
  .intemediateOperationN()
  .terminalOperation();
Tampilan umum pipa

Perbandingan metode penengah lan terminal:

penengah terminal
Jinis bali Stream ora aStream
Bisa digabungake karo macem-macem cara saka jinis sing padha kanggo mbentuk pipa ya wis ora
Jumlah metode ing pipa siji sembarang ora luwih saka siji
Ngasilake asil pungkasan ora ya wis
Miwiti ngolah data ing stream ora ya wis

Ayo katon ing conto.

Upaminipun kita duwe klub kanggo penyayang kewan. Besok klub mengeti Ginger Cat Day. Klub kasebut nduweni pamilik pet, sing saben duwe dhaptar pets. Padha ora winates kanggo kucing.

Tugas: sampeyan kudu ngenali kabeh jeneng kabeh kucing jahe supaya bisa nggawe kertu ucapan pribadi kanggo "liburan profesional" sesuk. Kertu ucapan kudu diurutake miturut umur kucing, saka sing paling tuwa nganti paling enom.

Kaping pisanan, kita nyedhiyakake sawetara kelas kanggo mbantu ngrampungake tugas iki:

public enum Color {
   WHITE,
   BLACK,
   DARK_GREY,
   LIGHT_GREY,
   FOXY,
   GREEN,
   YELLOW,
   BLUE,
   MAGENTA
}
public abstract class Animal {
   private String name;
   private Color color;
   private int age;

   public Animal(String name, Color color, int age) {
      this.name = name;
      this.color = color;
      this.age = age;
   }

   public String getName() {
      return name;
   }

   public Color getColor() {
      return color;
   }

   public int getAge() {
      return age;
   }
}
public class Cat extends Animal {
   public Cat(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Dog extends Animal {
   public Dog(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Parrot extends Animal {
   public Parrot(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Pig extends Animal {
   public Pig(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Snake extends Animal {
   public Snake(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Owner {
   private String name;
   private List<Animal> pets = new ArrayList<>();

   public Owner(String name) {
      this.name = name;
   }

   public List<Animal> getPets() {
      return pets;
   }
}

Saiki ayo goleki Selectorkelas, ing ngendi pilihan bakal digawe miturut kritéria sing ditemtokake:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Selector {
   private static List<Owner> owners;

   private static void initData() {
      final Owner owner1 = new Owner("Ronan Turner");
      owner1.getPets().addAll(List.of(
            new Cat("Baron", Color.BLACK, 3),
            new Cat("Sultan", Color.DARK_GREY, 4),
            new Dog("Elsa", Color.WHITE, 0)
      ));

      final Owner owner2 = new Owner("Scarlet Murray");
      owner2.getPets().addAll(List.of(
            new Cat("Ginger", Color.FOXY, 7),
            new Cat("Oscar", Color.FOXY, 5),
            new Parrot("Admiral", Color.BLUE, 3)
      ));

      final Owner owner3 = new Owner("Felicity Mason");
      owner3.getPets().addAll(List.of(
            new Dog("Arnold", Color.FOXY, 3),
            new Pig("Vacuum Cleaner", Color.LIGHT_GREY, 8)
      ));

      final Owner owner4 = new Owner("Mitchell Stone");
      owner4.getPets().addAll(List.of(
            new Snake("Mr. Boa", Color.DARK_GREY, 2)
      ));

      final Owner owner5 = new Owner("Jonathan Snyder");
      owner5.getPets().addAll(List.of(
            new Cat("Fisher", Color.BLACK, 16),
            new Cat("Zorro", Color.FOXY, 14),
            new Cat("Margo", Color.WHITE, 3),
            new Cat("Brawler", Color.DARK_GREY, 1)
      ));

      owners = List.of(owner1, owner2, owner3, owner4, owner5);
   }
}

Sing isih ana yaiku nambah kode menyang mainmetode kasebut. Saiki, kita pisanan nelpon initData()cara, kang populates dhaftar pamilik pet ing klub. Banjur kita milih jeneng kucing jahe sing diurutake miturut umur kanthi urutan mudhun.

Pisanan, ayo goleki kode sing ora nggunakake stream kanggo ngrampungake tugas iki:

public static void main(String[] args) {
   initData();

   List<String> findNames = new ArrayList<>();
   List<Cat> findCats = new ArrayList<>();
   for (Owner owner : owners) {
      for (Animal pet : owner.getPets()) {
         if (Cat.class.equals(pet.getClass()) && Color.FOXY == pet.getColor()) {
            findCats.add((Cat) pet);
         }
      }
   }

   Collections.sort(findCats, new Comparator<Cat>() {
      public int compare(Cat o1, Cat o2) {
         return o2.getAge() - o1.getAge();
      }
   });

   for (Cat cat : findCats) {
      findNames.add(cat.getName());
   }

   findNames.forEach(System.out::println);
}

Saiki ayo goleki alternatif:

public static void main(String[] args) {
   initData();

   final List<String> findNames = owners.stream()
           .flatMap(owner -> owner.getPets().stream())
           .filter(pet -> Cat.class.equals(pet.getClass()))
           .filter(cat -> Color.FOXY == cat.getColor())
           .sorted((o1, o2) -> o2.getAge() - o1.getAge())
           .map(Animal::getName)
           .collect(Collectors.toList());

   findNames.forEach(System.out::println);
}

Kaya sing sampeyan ngerteni, kode kasebut luwih kompak. Kajaba iku, saben baris pipa stream minangka tumindak siji, saengga bisa diwaca kaya ukara ing basa Inggris:

.flatMap(owner -> owner.getPets().stream())
Pindhah saka a Stream<Owner>menyang aStream<Pet>
.filter(pet -> Cat.class.equals(pet.getClass()))
Simpen mung kucing ing aliran data
.filter(cat -> Color.FOXY == cat.getColor())
Simpen mung kucing jahe ing aliran data
.sorted((o1, o2) -> o2.getAge() - o1.getAge())
Urut miturut umur ing urutan mudhun
.map(Animal::getName)
Njaluk jeneng
.collect(Collectors.toList())
Sijine asil menyang dhaptar

3. Nggawe stream

Kelas kasebut Streamduwe telung cara sing durung kita bahas. Tujuan saka telung cara iki yaiku nggawe benang anyar.

Stream<T>.of(T obj)cara

Cara of()nggawe stream sing kasusun saka unsur siji. Iki biasane dibutuhake nalika, ngomong, fungsi njupuk Stream<T>obyek minangka bantahan, nanging sampeyan mung duwe Tobyek. Banjur sampeyan bisa kanthi gampang lan gampang nggunakake of()cara kanggo entuk stream sing kasusun saka siji unsur .

Tuladha:

Stream<Integer> stream = Stream.of(1);

Stream<T> Stream.of(T obj1, T obj2, T obj3, ...)cara

Cara of()nggawe stream sing kasusun saka unsur liwati . Sembarang nomer unsur diijini. Tuladha:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);

Stream<T> Stream.generate(Supplier<T> obj)cara

Cara kasebut generate()ngidini sampeyan nyetel aturan sing bakal digunakake kanggo ngasilake unsur stream sabanjure nalika dijaluk. Contone, sampeyan bisa menehi nomer acak saben wektu.

Tuladha:

Stream<Double> s = Stream.generate(Math::random);

Stream<T> Stream.concat(Stream<T> a, Stream<T> b)cara

Cara kasebut concat()nggabungake loro aliran liwat dadi siji . Nalika data diwaca, diwaca dhisik saka aliran pisanan, banjur saka aliran kapindho. Tuladha:

Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = Stream.of(10, 11, 12, 13, 14);
Stream<Integer> result = Stream.concat(stream1, stream2);

4. Nyaring data

Cara 6 liyane nggawe aliran data anyar, ngidini sampeyan nggabungake aliran menyang rantai (utawa saluran pipa) kanthi kerumitan sing beda-beda.

Stream<T> filter(Predicate<T>)cara

Cara iki ngasilake stream data anyar sing nyaring aliran data sumber miturut aturan liwati . Cara kasebut kudu diarani obyek sing jinise Stream<T>.

Sampeyan bisa nemtokake aturan nyaring nggunakake fungsi lambda , kang compiler banjur bakal diowahi kanggo Predicate<T>obyek.

Tuladha:

Aliran sing dirantai Panjelasan
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x < 3));

Simpen mung nomer kurang saka telung
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x > 0));

Simpen mung nomer luwih saka nul

Stream<T> sorted(Comparator<T>)cara

Cara iki ngasilake aliran data anyar sing ngurutake data ing aliran sumber . Sampeyan pass ing comparator , kang mranata aturan kanggo mbandingaken loro unsur stream data.

Stream<T> distinct()cara

Cara iki ngasilake aliran data anyar sing mung ngemot unsur unik ing aliran data sumber . Kabeh data duplikat dibuwak. Tuladha:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.distinct(); // 1, 2, 3, 4, 5

Stream<T> peek(Consumer<T>)cara

Cara iki ngasilake aliran data anyar , sanajan data ing kono padha karo aliran sumber. Nanging nalika unsur sabanjuré dijaluk saka stream, fungsi sing liwati kanggo peek()cara bakal disebut karo.

Yen sampeyan ngliwati fungsi kasebut System.out::printlnmenyang peek()metode kasebut, kabeh obyek bakal ditampilake nalika bakal ngliwati aliran kasebut.

Stream<T> limit(int n)cara

Cara iki ngasilake aliran data anyar sing mungn ngemot unsur pisanan ing aliran data sumber . Kabeh data liyane dibuwak. Tuladha:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.limit(3); // 1, 2, 3

Stream<T> skip(int n)cara

Cara iki ngasilake aliran data anyar sing ngemot kabeh unsur sing padha karo aliran sumber , nanging mlumpat (nglirwakake) unsur pisanan n. Tuladha:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.skip(3); // 4, 5, 2, 2, 2, 3, 4