Stream1. वर्गाच्या पद्धतींची यादी

डेटा प्रवाहांची साखळी तयार करणेStream सोपे करण्यासाठी वर्ग तयार केला गेला . हे साध्य करण्यासाठी, वर्गामध्ये नवीन वस्तू परत आणणाऱ्या पद्धती आहेत .Stream<T>Stream

यापैकी प्रत्येक डेटा प्रवाह एक साधी क्रिया करतो, परंतु जर तुम्ही त्यांना साखळ्यांमध्ये एकत्र केले आणि मनोरंजक लॅम्बडा फंक्शन्स जोडले , तर तुम्हाला हवे असलेले आउटपुट तयार करण्यासाठी तुमच्याकडे एक शक्तिशाली यंत्रणा आहे. लवकरच आपण स्वत: साठी पहाल.

येथे वर्गाच्या पद्धती आहेत Stream(केवळ सर्वात मूलभूत):

पद्धती वर्णन
Stream<T> of()
ऑब्जेक्ट्सच्या सेटमधून एक प्रवाह तयार करते
Stream<T> generate()
निर्दिष्ट नियमानुसार प्रवाह व्युत्पन्न करते
Stream<T> concat()
दोन प्रवाह एकत्र करतात
Stream<T> filter()
डेटा फिल्टर करते, फक्त निर्दिष्ट नियमाशी जुळणारा डेटा पास करते
Stream<T> distinct()
डुप्लिकेट काढून टाकते. आधीच समोर आलेला डेटा पास करत नाही
Stream<T> sorted()
डेटाची क्रमवारी लावते
Stream<T> peek()
प्रवाहातील प्रत्येक घटकावर क्रिया करते
Stream<T> limit(n)
तो निर्दिष्‍ट मर्यादेपेक्षा मोठा नसावा यासाठी कट केलेला प्रवाह परत करतो
Stream<T> skip(n)
प्रथम n घटक वगळते
Stream<R> map()
डेटा एका प्रकारातून दुसऱ्या प्रकारात रूपांतरित करते
Stream<R> flatMap()
डेटा एका प्रकारातून दुसऱ्या प्रकारात रूपांतरित करते
boolean anyMatch()
प्रवाहात निर्दिष्ट नियमाशी जुळणारा किमान एक घटक आहे का ते तपासते
boolean allMatch()
प्रवाहातील सर्व घटक निर्दिष्ट नियमाशी जुळतात का ते तपासते
boolean noneMatch()
प्रवाहातील कोणतेही घटक निर्दिष्ट नियमाशी जुळत नाहीत का ते तपासते
Optional<T> findFirst()
नियमाशी जुळणारा पहिला घटक सापडतो
Optional<T> findAny()
नियमाशी जुळणारा प्रवाहातील कोणताही घटक मिळवतो
Optional<T> min()
डेटा प्रवाहातील किमान घटक शोधते
Optional<T> max()
डेटा प्रवाहातील कमाल घटक मिळवते
long count()
डेटा प्रवाहातील घटकांची संख्या मिळवते
R collect()
प्रवाहातील सर्व डेटा वाचतो आणि संग्रह म्हणून परत करतो

Stream2. वर्गाद्वारे इंटरमीडिएट आणि टर्मिनल ऑपरेशन्स

जसे तुम्ही बघू शकता, वरील सारणीतील सर्व पद्धती a परत करत नाहीत Stream. हे या वस्तुस्थितीशी संबंधित आहे की वर्गाच्या पद्धती मध्यवर्ती (ज्याला नॉन-टर्मिनल देखील म्हणतात ) पद्धती आणि टर्मिनल पद्धतींमध्ये Streamविभागल्या जाऊ शकतात .

मध्यवर्ती पद्धती

इंटरमीडिएट पद्धती इंटरफेस लागू करणारी ऑब्जेक्ट परत करतात Streamआणि त्यांना एकत्र जोडले जाऊ शकते.

टर्मिनल पद्धती

टर्मिनल पद्धती a पेक्षा वेगळे मूल्य परत करतात Stream.

पद्धत कॉल पाइपलाइन

अशा प्रकारे, तुम्ही कितीही इंटरमीडिएट पद्धती आणि शेवटी एकच टर्मिनल पद्धत कॉल असलेली स्ट्रीम पाइपलाइन तयार करू शकता. कोड वाचनीयता वाढवताना हा दृष्टिकोन तुम्हाला जटिल तर्कशास्त्र लागू करू देतो.

पद्धत कॉल पाइपलाइन

डेटा प्रवाहातील डेटा अजिबात बदलत नाही. इंटरमीडिएट पद्धतींची साखळी ही डेटा प्रोसेसिंग पाइपलाइन निर्दिष्ट करण्याचा एक चपखल (घोषणात्मक) मार्ग आहे जी टर्मिनल पद्धत कॉल केल्यानंतर कार्यान्वित केली जाईल.

दुसऱ्या शब्दांत, जर टर्मिनल पद्धत कॉल केली नाही, तर डेटा प्रवाहातील डेटावर कोणत्याही प्रकारे प्रक्रिया केली जात नाही. टर्मिनल पद्धत कॉल केल्यानंतरच डेटावर प्रवाह पाइपलाइनमध्ये निर्दिष्ट केलेल्या नियमांनुसार प्रक्रिया करणे सुरू होते.

stream()
  .intemediateOperation1()
  .intemediateOperation2()
  ...
  .intemediateOperationN()
  .terminalOperation();
पाइपलाइनचे सामान्य स्वरूप

इंटरमीडिएट आणि टर्मिनल पद्धतींची तुलना:

मध्यवर्ती टर्मिनल
परतीचा प्रकार Stream नाही aStream
पाइपलाइन तयार करण्यासाठी एकाच प्रकारच्या अनेक पद्धतींसह एकत्र केले जाऊ शकते होय नाही
एका पाइपलाइनमधील पद्धतींची संख्या कोणतेही एकापेक्षा जास्त नाही
अंतिम परिणाम उत्पन्न करते नाही होय
प्रवाहातील डेटावर प्रक्रिया करणे सुरू करते नाही होय

एक उदाहरण पाहू.

समजा आपल्याकडे प्राणीप्रेमींसाठी एक क्लब आहे. उद्या क्लब जिंजर कॅट डे साजरा करेल. क्लबमध्ये पाळीव प्राणी मालक आहेत, त्यापैकी प्रत्येक पाळीव प्राण्यांची यादी आहे. ते फक्त मांजरींपुरते मर्यादित नाहीत.

कार्य: उद्याच्या "व्यावसायिक सुट्टी" साठी त्यांच्यासाठी वैयक्तिकृत ग्रीटिंग कार्ड तयार करण्यासाठी तुम्हाला सर्व आल्या मांजरींची सर्व नावे ओळखण्याची आवश्यकता आहे. ग्रीटिंग कार्ड्स मांजरीच्या वयानुसार, सर्वात वयस्कर ते सर्वात लहान पर्यंत क्रमवारी लावली पाहिजेत.

प्रथम, आम्ही हे कार्य सोडवण्यासाठी काही वर्ग प्रदान करतो:

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;
   }
}

आता वर्ग पाहू Selector, जिथे निवड निर्दिष्ट निकषांनुसार केली जाईल:

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);
   }
}

जे राहते ते म्हणजे पद्धतीमध्ये कोड जोडणे main. सध्या, आम्ही प्रथम initData()पद्धत कॉल करतो, जी क्लबमधील पाळीव प्राण्यांच्या मालकांची यादी तयार करते. मग आम्ही अदरक मांजरींची नावे त्यांच्या वयानुसार उतरत्या क्रमाने निवडतो.

प्रथम, हे कार्य सोडवण्यासाठी स्ट्रीम न वापरणारा कोड पाहू:

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);
}

आता एक पर्याय पाहू:

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);
}

जसे आपण पाहू शकता, कोड अधिक कॉम्पॅक्ट आहे. याव्यतिरिक्त, स्ट्रीम पाइपलाइनची प्रत्येक ओळ एकच क्रिया आहे, म्हणून ती इंग्रजीतील वाक्यांप्रमाणे वाचली जाऊ शकतात:

.flatMap(owner -> owner.getPets().stream())
a Stream<Owner>वरून a वर जाStream<Pet>
.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())
निकाल सूचीमध्ये ठेवा

3. प्रवाह तयार करणे

वर्गात Streamतीन पद्धती आहेत ज्या आम्ही अद्याप कव्हर केलेल्या नाहीत. या तीन पद्धतींचा उद्देश नवीन धागे तयार करणे हा आहे.

Stream<T>.of(T obj)पद्धत

पद्धत of()एक प्रवाह तयार करते ज्यामध्ये एक घटक असतो. हे सहसा आवश्यक असते जेव्हा, म्हणा, फंक्शन एखादे Stream<T>ऑब्जेक्ट एक युक्तिवाद म्हणून घेते, परंतु आपल्याकडे फक्त एक Tऑब्जेक्ट आहे. मग तुम्ही एकच घटक असलेला प्रवाहof() मिळविण्यासाठी पद्धत सहज आणि सहज वापरू शकता .

उदाहरण:

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

Stream<T> Stream.of(T obj1, T obj2, T obj3, ...)पद्धत

पद्धत of()एक प्रवाह तयार करते ज्यामध्ये उत्तीर्ण घटक असतात . कितीही घटकांना परवानगी आहे. उदाहरण:

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

Stream<T> Stream.generate(Supplier<T> obj)पद्धत

पद्धत generate()तुम्हाला एक नियम सेट करू देते जी विनंती केली जाते तेव्हा प्रवाहाचा पुढील घटक व्युत्पन्न करण्यासाठी वापरली जाईल. उदाहरणार्थ, तुम्ही प्रत्येक वेळी यादृच्छिक क्रमांक देऊ शकता .

उदाहरण:

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

Stream<T> Stream.concat(Stream<T> a, Stream<T> b)पद्धत

ही concat()पद्धत दोन उत्तीर्ण झालेल्या प्रवाहांना एकात जोडते . जेव्हा डेटा वाचला जातो, तेव्हा तो प्रथम पहिल्या प्रवाहातून वाचला जातो आणि नंतर दुसऱ्यामधून. उदाहरण:

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. डेटा फिल्टर करणे

आणखी 6 पद्धती नवीन डेटा प्रवाह तयार करतात, ज्यामुळे तुम्ही प्रवाहांना वेगवेगळ्या जटिलतेच्या साखळी (किंवा पाइपलाइन) मध्ये एकत्र करू शकता.

Stream<T> filter(Predicate<T>)पद्धत

ही पद्धत नवीन डेटा प्रवाह परत करते जी पास केलेल्या नियमानुसार स्त्रोत डेटा प्रवाह फिल्टर करते . ज्या ऑब्जेक्टचा प्रकार आहे त्यावर पद्धत कॉल करणे आवश्यक आहे .Stream<T>

तुम्ही lambda फंक्शन वापरून फिल्टरिंग नियम निर्दिष्ट करू शकता , जे कंपाइलर नंतर ऑब्जेक्टमध्ये रूपांतरित करेल Predicate<T>.

उदाहरणे:

साखळदंड प्रवाह स्पष्टीकरण
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x < 3));

फक्त तीन पेक्षा कमी संख्या ठेवा
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x > 0));

फक्त शून्यापेक्षा जास्त संख्या ठेवा

Stream<T> sorted(Comparator<T>)पद्धत

ही पद्धत नवीन डेटा प्रवाह परत करते जी स्त्रोत प्रवाहातील डेटाची क्रमवारी लावते . तुम्ही तुलनाकर्ता मध्ये पास करता , जे डेटा प्रवाहाच्या दोन घटकांची तुलना करण्यासाठी नियम सेट करते.

Stream<T> distinct()पद्धत

ही पद्धत एक नवीन डेटा प्रवाह परत करते ज्यामध्ये स्त्रोत डेटा प्रवाहातील केवळ अद्वितीय घटक असतात . सर्व डुप्लिकेट डेटा टाकून दिला आहे. उदाहरण:

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>)पद्धत

ही पद्धत नवीन डेटा प्रवाह परत करते , जरी त्यातील डेटा स्त्रोत प्रवाहाप्रमाणेच आहे. परंतु जेव्हा स्ट्रीममधून पुढील घटकाची विनंती केली जाते, तेव्हा तुम्ही मेथडमध्ये पास केलेले फंक्शनpeek() त्याच्यासोबत कॉल केले जाते.

जर तुम्ही फंक्शनला मेथडमध्ये पास केले System.out::println, peek()तर सर्व ऑब्जेक्ट्स स्ट्रीममधून गेल्यावर प्रदर्शित होतील.

Stream<T> limit(int n)पद्धत

ही पद्धत एक नवीन डेटा प्रवाह परत करते ज्यामध्ये स्त्रोत डेटा प्रवाहातील फक्त प्रथम nघटक असतात . इतर सर्व डेटा टाकून दिला आहे. उदाहरण:

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)पद्धत

ही पद्धत नवीन डेटा प्रवाह परत करते ज्यात स्त्रोत प्रवाह सारखे सर्व घटक असतात , परंतु प्रथम घटक वगळले जातात (दुर्लक्षित). nउदाहरण:

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