Streams এর Operations

Java Streams API - জাভা ফাংশনাল প্রোগ্রামিং (Java Functional Programming) - Java Technologies

353

Java 8 এ Streams API চালু করা হয়, যা Functional Programming ধারণাকে Java তে নিয়ে আসে। Streams হল একটি সিকোয়েন্স বা ধারাবাহিক ডেটা যা বিভিন্ন ধরনের অপারেশন (যেমন, ফিল্টার, ম্যাপ, সোর্ট) এর মাধ্যমে প্রসেস করা যায়। Streams API ব্যবহারের মাধ্যমে আপনি ডেটা পরিচালনা করতে পারেন খুবই কার্যকরভাবে, এবং এটি কোডকে আরও পরিষ্কার এবং সংক্ষিপ্ত করে তোলে।

Streams API দুই ধরনের অপারেশন প্রদান করে:

  1. Intermediate Operations (মাঝবর্তী অপারেশন)
  2. Terminal Operations (টার্মিনাল অপারেশন)

এই অপারেশনগুলোর মাধ্যমে আপনি স্ট্রিমের উপর বিভিন্ন প্রকারের কার্যাবলী এক্সিকিউট করতে পারেন।


1. Intermediate Operations (মাঝবর্তী অপারেশন)

Intermediate Operations হল এমন অপারেশন যেগুলি স্ট্রিমে প্রক্রিয়াকরণের একটি পর্যায় তৈরি করে, তবে এটি স্ট্রিমকে পরিবর্তন করে না, বরং একটি নতুন স্ট্রিম তৈরি করে। এই অপারেশনগুলি lazy (অলস) অপারেশন হিসেবে কাজ করে, অর্থাৎ তারা তখনই কার্যকরী হয় যখন একটি Terminal Operation প্রয়োগ করা হয়।

সাধারণ Intermediate Operations:

  • filter(): এটি একটি স্ট্রিম থেকে নির্দিষ্ট শর্ত মেনে এলিমেন্ট নির্বাচন করতে ব্যবহৃত হয়।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
    List<Integer> evenNumbers = numbers.stream()
                                        .filter(n -> n % 2 == 0)
                                        .collect(Collectors.toList());
    System.out.println(evenNumbers);  // Output: [2, 4, 6]
    
  • map(): এটি স্ট্রিমের প্রতিটি এলিমেন্টকে একটি ফাংশন প্রয়োগ করে পরিবর্তন করে। এর মাধ্যমে আপনি স্ট্রিমের ডেটার আকার বা রূপ পরিবর্তন করতে পারেন।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
    List<Integer> squares = numbers.stream()
                                    .map(n -> n * n)
                                    .collect(Collectors.toList());
    System.out.println(squares);  // Output: [1, 4, 9, 16]
    
  • distinct(): এটি স্ট্রিম থেকে পুনরাবৃত্তি (duplicates) মুছে দেয়।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
    List<Integer> distinctNumbers = numbers.stream()
                                           .distinct()
                                           .collect(Collectors.toList());
    System.out.println(distinctNumbers);  // Output: [1, 2, 3, 4, 5]
    
  • sorted(): এটি স্ট্রিমের এলিমেন্টগুলোকে স্বাভাবিক ক্রম বা কাস্টম কম্প্যারেটর ব্যবহার করে সাজায়।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(5, 3, 4, 1, 2);
    List<Integer> sortedNumbers = numbers.stream()
                                         .sorted()
                                         .collect(Collectors.toList());
    System.out.println(sortedNumbers);  // Output: [1, 2, 3, 4, 5]
    
  • flatMap(): এটি স্ট্রিমের প্রতিটি এলিমেন্টের মধ্যে থাকা সাব-স্ট্রিমগুলোকে একত্রিত করে একটি নতুন স্ট্রিম তৈরি করে।

    উদাহরণ:

    List<List<Integer>> listOfLists = Arrays.asList(
        Arrays.asList(1, 2, 3),
        Arrays.asList(4, 5, 6),
        Arrays.asList(7, 8)
    );
    List<Integer> flatList = listOfLists.stream()
                                        .flatMap(List::stream)
                                        .collect(Collectors.toList());
    System.out.println(flatList);  // Output: [1, 2, 3, 4, 5, 6, 7, 8]
    

2. Terminal Operations (টার্মিনাল অপারেশন)

Terminal Operations হল অপারেশন যা স্ট্রিমের শেষ কার্যক্রমে ঘটে এবং এটি স্ট্রিমকে এক্সিকিউট করে বা একটি ফলাফল প্রদান করে। একবার একটি টার্মিনাল অপারেশন প্রয়োগ করা হলে, স্ট্রিমের মধ্যে আর কোনো অপারেশন করা যায় না (স্ট্রিম "consumed" হয়ে যায়)।

সাধারণ Terminal Operations:

  • forEach(): স্ট্রিমের প্রতিটি এলিমেন্টের জন্য একটি অ্যাকশন সম্পাদন করতে ব্যবহৃত হয়।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    numbers.stream().forEach(n -> System.out.println(n));  // Output: 1 2 3 4 5
    
  • collect(): এটি একটি স্ট্রিমের এলিমেন্টকে একটি কন্টেইনার (যেমন লিস্ট, সেট) বা একত্রিতভাবে সংগ্রহ করতে ব্যবহৃত হয়। এটি সবচেয়ে বেশি ব্যবহৃত টার্মিনাল অপারেশন।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
    List<Integer> squares = numbers.stream()
                                    .map(n -> n * n)
                                    .collect(Collectors.toList());
    System.out.println(squares);  // Output: [1, 4, 9, 16]
    
  • reduce(): এটি স্ট্রিমের সমস্ত এলিমেন্টগুলিকে একটি একক মানে রিডিউস (সামগ্রিকভাবে) করতে ব্যবহৃত হয়। এটি binary operator ব্যবহার করে একটি একক ফলাফল তৈরি করে।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
    int sum = numbers.stream()
                     .reduce(0, (a, b) -> a + b);
    System.out.println(sum);  // Output: 10
    
  • count(): এটি স্ট্রিমের উপাদানের সংখ্যা প্রদান করে।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    long count = numbers.stream()
                         .count();
    System.out.println(count);  // Output: 5
    
  • anyMatch(), allMatch(), noneMatch(): এগুলি স্ট্রিমের মধ্যে কোনো একটি শর্তের সাথে এলিমেন্ট মিলছে কিনা তা চেক করে।

    • anyMatch(): শর্ত পূরণ করলে true ফেরত দেয়।
    • allMatch(): সবগুলো শর্ত পূরণ করলে true ফেরত দেয়।
    • noneMatch(): কোনো শর্ত পূরণ না হলে true ফেরত দেয়।

    উদাহরণ:

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    
    boolean anyEven = numbers.stream()
                             .anyMatch(n -> n % 2 == 0);
    System.out.println(anyEven);  // Output: true
    
    boolean allEven = numbers.stream()
                             .allMatch(n -> n % 2 == 0);
    System.out.println(allEven);  // Output: false
    

3. Combining Operations (অপারেশন একত্রিত করা)

Streams API তে আপনি Intermediate এবং Terminal Operations একসাথে ব্যবহার করে শক্তিশালী এবং কার্যকরী স্ট্রিম অপারেশন তৈরি করতে পারেন।

List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
List<String> result = words.stream()
                           .filter(w -> w.length() > 5)
                           .map(String::toUpperCase)
                           .sorted()
                           .collect(Collectors.toList());
System.out.println(result);  // Output: [BANANA, CHERRY]

এখানে, স্ট্রিমের মধ্যে filter, map, sorted, এবং collect অপারেশনগুলো একত্রিত করা হয়েছে, যা Functional Programming কনসেপ্টে খুবই সাধারণ।


4. Parallel Streams (প্যারালাল স্ট্রিমস)

Streams API তে Parallel Streams ব্যবহারের মাধ্যমে আপনি ডেটার মধ্যে multithreading প্রয়োগ করতে পারেন, যা বড় ডেটা সেট প্রক্রিয়াকরণে সহায়তা করে।

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.parallelStream()
                 .reduce(0, (a, b) -> a + b);
System.out.println(sum);  // Output: 15

Parallel Streams কনকারেন্ট এক্সিকিউশন সিস্টেম ব্যবহারের মাধ্যমে কার্যকরীভাবে ডেটা প্রসেস করতে সক্ষম হয়, বিশেষ করে বড় ডেটা সেটের জন্য এটি দ্রুত হয়।


সারাংশ:

Java Streams API ফাংশনাল প্রোগ্রামিং কনসেপ্টকে Java তে নিয়ে এসেছে এবং ডেটা প্রক্রিয়াকরণে IntermediateTerminal Operations এর মাধ্যমে খুবই কার্যকরী এবং সংক্ষিপ্ত কোড লেখার সুবিধা দিয়েছে। filter, map, reduce, collect, sorted সহ অন্যান্য স্ট্রিম অপারেশনগুলো আপনার কোডকে আরও পরিষ্কার, মডুলার এবং রিডেবল করে তোলে। Parallel Streams ব্যবহার করে আপনি প্যারালাল প্রসেসিং এর সুবিধা পেতে পারেন, যা বড় ডেটা সেট প্রক্রিয়াকরণের জন্য অত্যন্ত কার্যকর।

Content added By
Promotion

Are you sure to start over?

Loading...