জাভা প্রোগ্রামিং # ৭ – অ্যারে – ১

লুপ গেলো। কন্ডিশনাল গেলো। এইবার আমরা একটু বড় জিনিস – অ্যারে, স্ট্রিং এগুলো নিয়ে কাবজাব করার জন্য রেডি। তবে এক পোস্টে স্ট্রিং আর অ্যারে নিয়ে কথা বলা ঝামেলা। তাই এই পোস্ট শুধু অ্যারে এর জন্য।

For Dummies – অ্যারে কি জিনিস?

অ্যারে কি জিনিস সেটার জানার আগে একটা বিষয় পরিষ্কার করা দরকার। কম্পিউটার মেমরি কি জিনিস? আর ভেরিয়েবল ডিক্লেয়ার করলে সেটা মেমরিতে কীভাবে থাকে?

মেমরি মানে মেমরি কার্ড না!

মেমরি কার্ড একটা স্টোরেজ ডিভাইস। কম্পিউটার মেমরি না। সঠিক ডেফিনিশনে গেলে মেমরি কম্পিউটারের সিপিউ এর অংশ। আজ অবধি শুনেছো কোনদিন কেউ ৩২ গিগাবাইট মাইক্রো এসডি কার্ড দিয়ে ইন্টেল কোর আই৭ প্রসেসর চালাচ্ছে? শোনার কথাও না। শুনলে যে বলবে তাকে নিজ দায়িত্বে পাবনায় দিয়ে আসবা।

সহজ সরল ভাষায়, কম্পিউটারের মেমরি হচ্ছে র‍্যাম রম এগুলো। এরা প্রসেসরের সাথে কানেক্টেড(কীভাবে কানেক্টেড দেখতে চাইলে ডেস্কটপ কম্পিউটারের কেস খুলে মাদারবোর্ড দেখে নিতে পারো। সাবধান, ল্যাপটপ খুলে আবার ১২ টা বাজাইয়ো না।) আমরা প্রোগ্রামিং এর সময় যেখানে ডেটা রাখি সেটা হচ্ছে র‍্যাম। র‍্যাম এর আবার গজনীর আমির খানের মতন ভুলে যাওয়ার রোগ আছে। আমির খান ১৫ মিনিট পরে ভুলে যেত। র‍্যাম কম্পিউটার বন্ধ হয়ে গেলে বা পাওয়ার চলে গেলে সব ভুলে যায়। এই আরকি। আবার অপারেটিং সিস্টেম র‍্যাম ফাঁকা রাখার জন্য অনেক সময় ঝাটা দিয়ে মেরে মানে ক্লিন করেও র‍্যাম থেকে অপ্রয়োজনীয় ডেটা ফেলে দেয়। র‍্যামে কীভাবে সব কাজ হয় সেটা কম্পিউটার আর্কিটেকচার অ্যান্ড ডিজাইন এবং অপারেটিং সিস্টেমস ডিজাইন কোর্সের জিনিস তাই সেদিকে না যাই। ফোকাস!

যখন আমরা একটা ভ্যারিয়েবল ডিক্লেয়ার করি, ধরা যাক একটা int টাইপের ভেরিয়েবল তখন অপারেটিং সিস্টেম তার জন্য ৪ বাইট মানে ৩২ বিট জায়গা বরাদ্দ করে। (জাভা কোন টাইপের জন্য কি পরিমাণ জায়গা নেয় তার জন্য এই লিংক এর প্রথম দিকের লেখাগুলো পড়তে পারো। বেশী পড়তে যাইয়ো না। হারিয়ে যাবা।) এই ৩২ বিট জায়গা সে কই রাখে? অবশ্যই মেমরি কার্ডে রাখে না! সে এইটা রাখে র‍্যামে। কিন্তু র‍্যামে কি ডিরেক্ট নিয়ে রেখে দেয়? না ডিরেক্ট ও রাখে না। কম্পিউটার ভেরিয়েবল কি ধরণের সেটার উপর ডিপেন্ড করে মেমরিতে বিভিন্ন ডেটা স্ট্রাকচার যেমন স্ট্যাক, হিপ ইত্যাদিতে ভেরিয়েবল ডেটা অর্গানাইজ করে রাখা হয়। তুমি যদি দেখতে চাও যে, মেমরীতে কোন ইন্সট্রাকশন দিয়ে বা কোন ভেরিয়েবল লোড হচ্ছে, তুমি জাভা বাইটকোড javap দিয়ে পড়ে নিতে পারো। (এ বিষয়ে আগেই দেখিয়েছি কীভাবে করা লাগে) বাট অ্যাডভান্সড জিনিস, দেখতে গিয়ে না বুঝলে মন খারাপ করার কিছু নেই।

এবার, অ্যারে কি জিনিস?

অ্যারে হচ্ছে একই টাইপের ভেরিয়েবলের একটা কালেকশন। int টাইপের অ্যারেতে শুধু int ডেটাই থাকে এবং ইত্যাদি ইত্যাদি। তোমরা C তে এইটা দেখে এসেছো। এখন প্রশ্ন হচ্ছে – অ্যারেতে ডেটা যখন রাখি থাকে ক্যামনে? কিংবা অ্যারে এর বৈশিষ্ট্য কি কি?

Imgur
আচ্ছা এই ছবি দেখলে কি মাথায় আসে? C তে শেখা জ্ঞান ইউস করো।
– একটা অ্যারে, সাইজ হচ্ছে ৫
– এর প্রতিটা ইলিমেন্ট এর কে অ্যাকসেস করা হয় ইন্ডেক্স দিয়ে
– ইন্ডেক্স এর মান শুরু হয় ০ থেকে। যখন লুপ চালিয়ে অ্যারে এর ইলিমেন্ট অ্যাকসেস করবে তখন ০ থেকে শুরু করা লাগবে।
– প্রতিটা ইলিমেন্ট একেকটা ভেরিয়েব্ল এবং মেমরীতে তারা আলাদা আলাদা জায়গা দখল করে। আমি যদি বলি একটা ৫ সাইজের ইন্টিজার অ্যারে তাহলে এর মোট সাইজ হচ্ছে ৫ X ৪ বাইট = ২০ বাইট।

C এর অ্যারে আর জাভার অ্যারে এর কনসেপ্ট একই। আলাদা কিছু না। তবে একটা জায়গায় পার্থক্য আছে। সেটা সামনেই আসছে।

জাভাতে অ্যারে ডিক্লেয়ার করা

int[] array = new int[size];

অর্থায় প্রথমে টাইপ লেখবো, এরপর [] দিয়ে বুঝাবো যে এইটা একটা অ্যারে। এরপর new দিয়ে আবার টাইপ এরপর সাইজ দিবো। আচ্ছা এইখানে new দিচ্ছি কেন?

এত new কেন?

Imgur

new এর কাজ কি বলার সময় এসে গেছে। It’s about time! new জাভা এর একটা কী ওয়ার্ড। এর কাজ হচ্ছে, মেমরীতে তোমার ভেরিয়েবলের জন্য জায়গা বরাদ্দ বা অ্যালোকেট করা। তো তুমি যখন অ্যারে বানাচ্ছো, তার কোন ইলিমেন্ট নিশ্চিত উগান্ডা, কোনটা কেনিয়া কোনটা আবার নেব্রাস্কা কিংবা কোনটা টাঙ্গাস্কায় থাকলে চলবে না। অ্যারে একটা কন্টিনিউয়াস কালেকশন। ধরো অ্যারে এর প্রথম ইলিমেন্ট যদি ০ অ্যাড্রেসে থাকে তাহলে ৫ সাইজের অ্যারের জন্য ০,১,২,৩,৪ এই ৫ টা অ্যাড্রেস রেখে দিতে হবে। এখন কম্পিউটারের মেমরী তো শুধু তোমার প্রোগ্রামের একলার না। তাকে সবাই ইউস করে। তাহলে তুমি কীভাবে নিশ্চিত করবে যে কন্টিনিউয়াস ৫ টা মেমরি অ্যাড্রেস তুমি পাচ্ছো? new কীওয়ার্ড দিয়ে তুমি বলে দিলা যে আমাকে এই অ্যারে এর জন্য size এর সমান সংখ্যক মেমরী অ্যাড্রেস অ্যালোকেট করে দিতে হবে। JVM তোমার কথামত সেটা করে দিবে।

কিন্তু………….

Imgur

ভালো প্রশ্ন। কেন লাগে কেন লাগে না? এর বড় কারণ হচ্ছে C প্রোগ্রামের মেমরী অ্যালোকেশন সিস্টেম আর জাভা প্রোগ্রামের মেমরী অ্যালোকেশন সিস্টেম এক না।

C এর মেমরী অ্যালোকেশন

C এর জন্ম যে যুগে ল্যাঙ্গুয়েজ সে যুগে কম্পিউটারে মেমরী ছিলো বাইট সাইজের। কিলোবাইট, মেগাবাইট, গিগাবাইট মেলা দূরের জিনিস। সেসময় প্রোগ্রামার দের প্রোগ্রাম কাজ করে কিনা তার চাইতে বেশি নজর রাখতে হতো প্রোগ্রাম মেমরী কেমন নিচ্ছে তার উপর। তাই ল্যাঙ্গুয়েজের ক্রিয়েটররা এমনভাবেই ল্যাঙ্গুয়েজ ডিজাইন করলেন যাতে প্রোগ্রামার হাতে ধরে মেমরী অ্যালোকেশনের কাজ করতে পারে এবং একেবারে র‍্যাম এর অ্যাড্রেস ধরে ধরে ফিক্স করতে পারে কোন ভেরিয়েবলের ভ্যালু কই যাবে, কই গেলে ভালো হবে।

কারো যদি প্লেস্টেশন ১ থেকে থাকে, এবং সেটাতে Crash Bandicoot খেলে থাকো, তাহলে তোমাদের জন্য ইনফো – প্লেস্টেশন ১ এর মোট র‍্যাম ছিলো ২ মেগাবাইট। সেটার মাঝে এই গেম রান করাতে কি পরিমাণ হ্যাপা পোহাতে হয়েছে চিন্তা করো। ভিডিও গেম ইন্ডাস্ট্রি বিশেষ করে বড় বড় টাইটেল মেকাররা C, C++ এর উপর ব্যাপকভাবে নির্ভরশীল। ইউ নো দা রিজন।

এর যেমন সুবিধা আছে তেমনি অসুবিধাও আছে। মেমরী অ্যালোকেশন ম্যানুয়াল হওয়াতে, কাজ শেষ হবার পরে মেমরী ক্লিন করে দেয়ার পুরো দায়িত্ব ছিলো প্রোগ্রামারের উপর। সে এই কাজ ভুলে গেলে শেষ। কম্পিউটার ক্র্যাশ থেকে শুরু করে নানাবিধ ঝামেলা হতো। কারণ প্রোগ্রাম এর কাজ শেষ হলে কী হবে মেমরী তো খালি করে নাই! এরপর, সব প্রোগ্রামে এত লো লেভেলের অপ্টিমাইজেশন দরকার ও ছিলো না। এইটা বেশ ঝামেলার ছিলো।

ম্যানুয়ালি মেমরী ম্যানেজ করা আইন নিজের হাতে তুলে নেয়ার মতন। তুলে নিলে নিজ দায়িত্বে নামাতে হয়।

Imgur

জাভা এর মেমরী অ্যালোকেশন

জাভার নির্মাতাদের একটা বড় উদ্দেশ্য ছিলো প্রচলিত ঝামেলা গুলো দূর করা। তারা মত দিলেন, যেহেতু জেভিএম একটা সেপারেট এনটিটি, সে সব প্ল্যাটফর্মের জন্য সেম – এইটাকে আরো ইন্টেলিজেন্ট করা যাক। তারা JVM কে একটা ম্যাজিকাল ক্ষমতা দিলেন । সে নিজে নিজে মেমরী ম্যানেজ করতে পারে, প্রোগ্রামের বলে দেয়া লাগে না। কাজ শেষ হলে মেমরী খালিও করে দিতে পারে। এইটাকে বলে garbage collection

প্রোগ্রামার এখন নির্ভার। তাকে ধরে ধরে সব ঠিক করা লাগবে না।

এজন্য জাভাতে যখন new দিয়ে অ্যালোকেট করতে বলো, তোমাকে চিন্তা করা লাগে না এরপর কি হবে। JVM বাকিটা করে নিবে।

তাহলে কি জাভাতে ম্যানুয়ালি মেমরী ম্যানেজ করা যাবে না?

না। সে অপশন নেই। এ কারণে জাভাতে C এর মতন পয়েন্টার নাই।

কেন জাভাতে ম্যানুয়াল মেমরী ম্যানেজমেন্ট নেই? কেন আমি মেমরি অ্যাক্সেস পাই না?

ডিয়ার ওয়াটসন, জেভিএম একটা ভার্চুয়াল মেশিন রিমেম্বার? ভার্চুয়াল মেশিনের নিজের মেমরী থাকে, কিন্তু সেটার কি ফিজিকাল এক্সিস্টেন্স আছে? নাই তো! জেভিএম মেমরী অ্যালোকেশন করে নিজের মেমরী থেকে। সেটার সাথে কম্পিউটারের মূল মেমরীর কোন যোগাযোগ থাকে না (যেমন C তে সরাসরি মূল মেমরী ইউস হয়)। তাই আমরা অ্যাকসেস পাই না।

Imgur

নতুন শব্দ – Instantiate ইন্সট্যানশিয়েট করা

new দিয়ে মেমরীতে কোন কিছুর জন্য জায়গা বরাদ্দ করাকে বলা হয় ইন্সটেনশিয়েট করা। এই শব্দটা অনেক ইউস করবো, মাথায় রাখো।

অ্যারে এর সাইজ কি বদলানো যায়?

একবার ইন্সটেনশিয়েট করে ফেললে অ্যারে এর সাইজ বদলানো যায় না। অ্যারে একটা ফিক্সড সাইজড স্ট্রাকচার। যদি এমন ধরনের অ্যারে চাও যেখানে অন ডিমান্ড সাইজ চেঞ্জ করা যাবে কিংবা সাইজ এর বেশি ইলিমেন্ট অ্যাড করা যাবে, তাহলে তার জন্য অ্যারে দিয়ে হবে না। এর জন্য বিকল্প স্ট্রাকচার আছে। সেটা আমরা পরে দেখবো।

Imgur

Let’s turn to some code

একটা প্রবলেম রেডি করি। ধরা যাক আমাকে একটা ১০ সাইজের অ্যারে নিতে হবে এবং ১০ ইনপুট অ্যারেতে রাখতে হবে, ইনপুট নেয়া শেষ হলে সব প্রিন্ট করতে হবে। তাহলে এমন হবে –

import java.util.Scanner;

public class ArrayInput {

    public static void main(String[] args) {

        // defining size beforehand is a good practice
        int SIZE = 10;
        int[] array = new int[SIZE];

        // declare scanner
        Scanner in = new Scanner(System.in);

        // take input
        for (int i = 0; i < SIZE; i++) {
            array[i] = in.nextInt();
        }

        // print
        for (int i = 0; i < SIZE; i++) {
            System.out.println(array[i]);
        }

        // close scanner
        in.close();
    }

}

এই একই কাজ C তে অনেকবার করেছো। চেনা চেনা লাগে? 😉

এবার ধরা যাক আমি আগে থেকে ৫ টা ভ্যালু দিয়ে একটা অ্যারে বানাবো। অর্থাত ইনপুট নেয়ার দরকার নেই। তাহলে প্রোগ্রাম এমন দাঁড়াবে –

public class ArrayDefined {

    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5};
        int SIZE = 5;

        // print
        for (int i = 0; i < SIZE; i++) {
            System.out.println(array[i]);
        }
    }

}

আচ্ছা এইখানে new দিলাম না কেন? এর কারণ হচ্ছে, যদি অ্যারে এর ইলিমেন্ট গুলো জানিয়ে দেই তাহলে JVM বাহাইন্ড দা সিন ইন্সটেনশিয়েশনের কাজ করে নেয়।

এখন, ধরো তুমি সাইজ নামক ভেরিয়েবলে সাইজ রাখলে না কোন কারণে এবং কেউ তোমাকে এমন একটা অ্যারে দিলো যার সাইজ তুমি জানো না। কীভাবে অ্যারে এর সাইজ বের করবা? তোমার জীবন সহজ করতে জাভাতে অ্যারে এর জন্য length নামে একটা প্রোপার্টি আছে। তাকে কল দিলেই চলবে।

array.length

<br />public class ArrayLength {

    public static void main(String[] args) {
        int[] array = {
            34, 56, 67, 689, 35, 44, 66, 666, 3456, 232
        };
        int sizeOfArray = array.length;

        System.out.println(sizeOfArray);
    }

}

আসলেই এত সোজা? – না আমি মজা নিচ্ছি না। রান করে দেখো! আচ্ছা এতো গেলো int অ্যারে। float, double ইত্যাদির অ্যারে এর জন্য ও সেম কাজ হবে। আর হ্যা জাভাতে String এর ও অ্যারে বানানো যায়। এবং সিনট্যাক্স একই।

এসাইনমেন্ট

  • একটা ক্যারেক্টার অ্যারে বানাও, তাতে কিছু ক্যারেক্টার রাখো। এবার আরেকটা অ্যারে নাও, সেটাতে ইউজার ইনপুট নাও। দুইটা অ্যারের বিজোড় ইন্ডেক্স এর ইলিমেন্ট সেম কিনা দেখো। যদি সেম হয় True প্রিন্ট করো নাহলে False প্রিন্ট করো। আমি একটা রাফ কোড দিচ্ছি।
public class Assignment1 {
    public static void main(String[] args) {
        char[] ar1 = {'h', 'e', 'l', 'l', 'o'};
        char[] ar2 = new char[ar1.length];

        // take input using Scanner

        // your code goes here! 

    }
}
  • একটা ইন্টিজার ভেরিয়েবলে অ্যারে সাইজ ইনপুট নাও, এরপর সেটা দিয়ে একটা যেকোন টাইপের অ্যারে ইন্সটেনশিয়েট করে তার সাইজ প্রিন্ট করো।

  • একটা ১০ সাইজের অ্যারে নাও, সেখানে ইউজার থেকে ইনপুট নাও। (int টাইপ এর)। এরপর অ্যারে এর সর্বোচ্চ ইলিমেন্ট টা বের করে প্রিন্ট করো। ধরো {1, 6, 99, -1} যদি অ্যারে হয় এর সর্বোচ্চ ইলিমেন্ট হবে 99

  • ধরো তুমি আজকে বাজারে গিয়েছিলে। অনেক বাজার করেছো। এখন তোমার আলসেমি লাগছে তাই হিসাব করতে ইচ্ছা করছে না। তোমার কাজটা সহজ করা যাক। দুইটা অ্যারে নাও। একটা String অ্যারে, যাতে থাকবে কি বাজার করলে মানে কেনা জিনিসের নাম, আরেকটা float অ্যারে। যাতে লেখা থাকবে যে জিনিসটার দাম কত। খেয়াল রাখবে নামের ইন্ডেক্স এর সাথে যাতে দামের ইনডেক্স এর মিল থাকে। ইনপুট না নিয়ে অ্যারেতে ভ্যালু রাখতে পারো। এবার দামের এভারেজ, সর্বোচ্চ সর্বনিম্ন মান বের করবে আর করবে। এরপর এভাবে প্রিন্ট করবে।

Average = 
Max : ProductName = price
Min : ProductName = price
  • তোমার বন্ধুর ও সেম প্রবলেম, কিন্তু বেচারা জাভা পারে না। তাই তোমাকে ইনপুট নিয়ে এবার কাজটা করতে হবে। ইউ নো দা ড্রিল 😉

অ্যারে কি শেষ?

সবে সিংগেল ডাইমেনশনাল অ্যারে দেখাইলাম। 2D, 3D ইত্যাদি এখনো বাকি। সেইটা পরের পোস্টে দেখাবো 🙂 এসাইনমেন্ট গুলো নিজে করে নিয়ো। দরকার লাগলে Google, Bing, DuckDuckGo যেখানে খুশি সার্চ দিতে মনে চায় দিতে পারো।

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

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

Google+ photo

You are commenting using your Google+ 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