Java Stream – takeWhile() ও dropWhile()

জাভা ৮ এর একটি গুরুত্বপূর্ণ ফিচার হল স্ট্রীম। এর মাধ্যমে জাভাতে declarative paradigm এর একটা টেস্ট পাওয়া যায়। ডেভেলপারদের কাজ সহজ করার জন্য জাভা ৯ এ স্ট্রীমে বেশ কিছু নতুন মেথড আনা হয়। এর মধ্যে দু’টি হলঃ dropWhile() ও takeWhile()।

dropWhile():

এটি Stream এর একটি intermediate operation, যা আরেকটি Stream রিটার্ন করে। এই মেথডটি Stream থেকে একটি করে element নেয়, আর given condition এর সাথে compare করে। condition এর রেজাল্ট যদি true রিটার্ন করে, তাহলে ঐ element কে ড্রপ করে। ফলস রিটার্ন করলে স্ট্রীমে add করে। আমরা এটিকে একটি নরমাল লুপের সাথে compare করতে পারি। লুপের কন্ডিশান ফলস হলে যেমন লুপ থেকে বের হয়ে যায়, তেমনি স্ট্রীমের যেকোন element এর জন্য একবার কন্ডিশানের রেজাল্ট ফলস পেলে পরবর্তী সব element ই dropWhile() যে স্ট্রীম রিটার্ন করে, সেই স্ট্রীমে এক এক করে চলে আসবে।

String collect = IntStream.range(1, 10)
        .dropWhile(value -> value < 4)
        .mapToObj(i -> ((Integer) i).toString())
        .collect(Collectors.joining(", "));
System.out.println(collect);

আমরা যদি এই কোডটা রান করি, দেখব যে, আউটপুটটা এমন আসছে।

4, 5, 6, 7, 8, 9

১ থেকে ৩ যেহেতু ৪ থেকে ছোট, তাই dropWhile() এই তিনটি নাম্বারকে ড্রপ করেছে। বাকিসব নাম্বারকে সে স্ট্রীমে নিয়ে নিয়েছে। আরেকটি এক্সাম্পল দেখিঃ

String s = IntStream.of(1, 10, 9, 20, 5, 4, 3, 2, 12)
        .dropWhile(i -> i < 12)
        .mapToObj(i -> ((Integer) i).toString())
        .collect(Collectors.joining(", "));
System.out.println(s);

এখানে IntStream এর প্রথম তিনটি element যেহেতু ১২ থেকে ছোট, এদেরকে dropWhile() পরবর্তী স্ট্রীমে নিবে না। ২০ যেহেতু ১২ থেকে বড়, condition ফলস হয়ে গেল। তাই ২০ থেকে বাকি সব element ই পরবর্তী স্ট্রীমে চলে আসবে। পরবর্তী ইন্টিজারগুলো ১২ থেকে বড় কি ছোট, নাকি সমান, সেটা আর বিবেচ্য হবে না। তারমানে আউটপুট হবে এমনঃ

20, 5, 4, 3, 2, 12

takeWhile():

takeWhile() হচ্ছে dropWhile() এর ঠিক উল্টো। এটাও একটা intermediate operation, যা আরেকটি স্ট্রীম রিটার্ন করে। given কন্ডিশনের উপর বেস করে পরের স্ট্রীমে ডাটা নিতে থাকে, যখনই কন্ডিশনের রেজাল্ট ফলস হয়, তখনই স্ট্রীমে element নেয়া বন্ধ করে দেয়।

String collect = IntStream.range(1, 10)
        .takeWhile(value -> value < 4)
        .mapToObj(i -> ((Integer) i).toString())
        .collect(Collectors.joining(", "));
System.out.println(collect);

এই কোডটুকু রান করলে দেখব যে, আউটপুট আসছে এমনঃ

1, 2, 3

১, ২ ও ৩ যেহেতু ৪ থেকে ছোট, তাই কন্ডিশনের রেজাল্ট true, তাই takeWhile() এদের স্ট্রীমে নিয়েছে। যখনই ৪ আসলে, তখনই কন্ডিশনের রেজাল্ট ফলস হল, তাই স্ট্রীমে নেয়া বন্ধ করে দিল। সাধারণ লুপের ভাষায় যেটাকে আমরা ব্রেক করা বলি।

এখন নিচের এই কোডটা যদি রান করে দেখিঃ

String collect = IntStream.of(10, 3, 2, 1, 12, 5, 100)
        .takeWhile(i -> i < 7)
        .mapToObj(i -> ((Integer) i).toString())
        .collect(Collectors.joining(", "));
System.out.println(collect);

দেখব যে, আউটপুট কিছুই আসেনি। কারণ, প্রথম ইন্টিজার ১০ এর ক্ষেত্রেই কন্ডিশন ফলস হয়ে গিয়েছে। ফলে takeWhile() স্ট্রীমে নেয়া বন্ধ করে দিয়েছে। যার কারণে এক্ষেত্রে collect স্ট্রিং এ একটি Empty String আসে।

তাহলে দেখলাম যে, dropWhile() একটি স্ট্রীমের শুরু থেকে given কন্ডিশন ফলস না হওয়া পর্যন্ত element ড্রপ করতে থাকে।কন্ডিশন একবার ফলস হলে সে স্ট্রীমের বাকি সব element ই নিয়ে ফেলে। আর takeWhile() একটি স্ট্রীমের শুরু থেকে given কন্ডিশন ফলস না হওয়া পর্যন্ত element take করতে থাকে। কন্ডিশন একবার ফলস হলে সে স্ট্রীমের আর কোন element ই নেয়না।

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s