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. ক্লাস দ্বারা মধ্যবর্তী এবং টার্মিনাল অপারেশন

আপনি দেখতে পাচ্ছেন, উপরের টেবিলের সমস্ত পদ্ধতি একটি রিটার্ন করে না Stream। এটি এই বিষয়টির সাথে সম্পর্কিত যে ক্লাসের পদ্ধতিগুলিকে মধ্যবর্তী ( অ-টার্মিনাল হিসাবেও পরিচিত ) পদ্ধতি এবং টার্মিনাল পদ্ধতিতে Streamবিভক্ত করা যেতে পারে ।

মধ্যবর্তী পদ্ধতি

ইন্টারমিডিয়েট পদ্ধতিগুলি এমন একটি বস্তু ফেরত দেয় যা Streamইন্টারফেসকে প্রয়োগ করে এবং সেগুলিকে একসাথে শৃঙ্খলিত করা যেতে পারে।

টার্মিনাল পদ্ধতি

টার্মিনাল পদ্ধতি একটি ছাড়া অন্য একটি মান প্রদান করে 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>

আপনি একটি ল্যাম্বডা ফাংশন ব্যবহার করে ফিল্টারিং নিয়ম নির্দিষ্ট করতে পারেন , যা কম্পাইলার একটি 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