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

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

কোথায় এবং কিভাবে এটি ব্যবহার করা যেতে পারে? ঠিক আছে, আমার সহপাঠীদের শেষ নামের সাথে একই অ্যাসাইনমেন্টের জন্য এটি আদর্শ হবে। যদি আমার নিজের সাজানোর অ্যালগরিদম লেখার পরিবর্তে ক্রমবর্ধমান ক্রমে মান সঞ্চয় করতে হয়, তবে আমাকে যা করতে হবে তা হল একটি ট্রিম্যাপ তৈরি করা এবং এতে মানগুলি রাখা।

এটি ক্রমবর্ধমান ক্রমে পূর্ণসংখ্যা এবং স্ট্রিংয়ের মতো প্রকারগুলিকে সাজায় । কিন্তু আপনি যদি TreeMap- এ আপনার নিজস্ব কাস্টম টাইপ রাখতে চান , তাহলে আপনার ক্লাসকে তুলনামূলক ইন্টারফেস প্রয়োগ করতে হবে , যাতে এটি compareTo() পদ্ধতি প্রয়োগ করে, যা নির্দেশ করে কিভাবে আপনার ক্লাসের উদাহরণগুলি সাজাতে হয়।

public class Person implements Comparable<Person> {

    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }@Override
    public int compareTo(Person person) {
        return person.getFirstName().compareTo(firstName);
    }

    @Override
    public String toString() {
        return "Person{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

আসুন compareTo() পদ্ধতিটিকে ওভাররাইড করি যাতে এটি বিপরীত বর্ণানুক্রমিক ক্রমে প্রথম নাম অনুসারে মানগুলি সাজায়:

TreeMap map = new TreeMap<Person, String>();

map.put(new Person("AA","BB"), "aa");
map.put(new Person("BB","BB"), "aa");
map.put(new Person("DD","BB"), "aa");
map.put(new Person("CC","BB"), "aa");

মানগুলি নিম্নলিখিত ক্রমে সংরক্ষণ করা হবে:

Person{firstName='DD', lastName='BB'}
Person{firstName='CC', lastName='BB'}
Person{firstName='BB', lastName='BB'}
Person{firstName='AA', lastName='BB'}

ট্রিম্যাপ ক্লাস নেভিগেবলম্যাপ ইন্টারফেস প্রয়োগ করে, যার ফলে সাজানো ম্যাপ ইন্টারফেস প্রসারিত হয়। এটি TreeMap ক্লাসকে সাজানো ক্রমে মান সংরক্ষণ করতে গাছ ব্যবহার করতে দেয়।

যেমন উইকিপিডিয়া বলে, একটি গাছ একটি স্ব-ভারসাম্যপূর্ণ বাইনারি অনুসন্ধান কাঠামো যা প্রথমে মান তুলনা করার পরে তার নোডগুলিতে ডেটা সংরক্ষণ করে।

সহজ কথায় বলতে গেলে, একটি লাল-কালো গাছ হল একটি ডাটা স্ট্রাকচার যা মূলের চেয়ে বড় হলে ডান সাবট্রিতে মান সংরক্ষণ করে এবং বাম সাবট্রিতে যদি সেগুলি কম হয়। এই বাস্তবায়ন খুব দ্রুত কাঠামোর মান খুঁজে পেতে পারে।

একটি লাল-কালো গাছ স্ব-ভারসাম্যপূর্ণ, তাই প্রতিটি নতুন মান ঢোকানোর সাথে সাথে এটি তার গঠন পরিবর্তন করে। প্রথমে যোগ করা মানটিকে প্রাথমিকভাবে রুট হিসাবে বিবেচনা করা হয়, তবে ভারসাম্য প্রক্রিয়া চলাকালীন অন্য একটি মান রুট হতে পারে।

আচ্ছা, এখন আপনি জানেন TreeMap কি এবং এটি কিভাবে কাজ করে।

মনে রাখবেন যে TreeMap শুধুমাত্র সেই বস্তুগুলিকে সঞ্চয় করতে পারে যার ক্লাস তুলনাযোগ্য ইন্টারফেস প্রয়োগ করে এবং compareTo() পদ্ধতিকে ওভাররাইড করে।

তবে আমরা যদি বিভিন্ন লাইব্রেরি থেকে লোড করা তৃতীয় পক্ষের ক্লাস ব্যবহার করি এবং সেগুলিতে তুলনামূলক প্রয়োগ করতে না পারি তবে কী হবে? এর জন্য একটি সমাধান আছে: আপনার নিজের তুলনাকারী লিখুন ।

Comparator হল একটি ইন্টারফেস যার একটি compare() পদ্ধতি রয়েছে। আমরা বস্তুর তুলনা করতে এবং একটি TreeMap এ সংরক্ষণ করতে এটি ব্যবহার করতে পারি।

Comparator<Person> comparator = new Comparator<Person>() {

    @Override
    public int compare(Person person1, Person person2) {
        return person1.getFirstName().compareTo(person2.getFirstName());
    }
};


TreeMap map = new TreeMap<Person, String>(comparator);

এই উদাহরণে, আমরা একটি কাস্টম তুলনাকারী তৈরি করেছি এবং ক্লাসে একটি TreeMap পাস করেছি।

জাভা 8 থেকে শুরু করে, আমরা ল্যাম্বডা এক্সপ্রেশন ব্যবহার করে এটি লিখতে পারি:

TreeMap map = new TreeMap<Person, String>((Person person1, Person person2) -> person1.getFirstName().compareTo(person2.getFirstName()));

অন্য কথায়, একটি TreeMap- এ মান সঞ্চয় করার জন্য , আপনাকে সেগুলি কীভাবে সাজাতে হবে তা উল্লেখ করতে হবে। এটি করার দুটি উপায় রয়েছে: Comparable প্রয়োগ করুন বা আপনার নিজের Comparator বাস্তবায়ন করুন ।

কিন্তু যদি আমরা একটি কী হিসাবে একটি TreeMap মধ্যে নাল করা প্রয়োজন? হ্যাশম্যাপ আপনাকে এটি করতে দেয়। হ্যাঁ, কিন্তু কিভাবে TreeMap এটি পরিচালনা করে?

TreeMap map = new TreeMap<Person, String>();
map.put (null, "Person");

এই কোডটি চালানো আমাদের একটি ত্রুটি দেয়:

java.base/java.util.TreeMap.put(TreeMap.java:561) এ থ্রেড "প্রধান" java.lang.NullPointerException-এ ব্যতিক্রম

সমস্যা হল যে অভ্যন্তরীণভাবে TreeMap ক্লাস compareTo() পদ্ধতি ব্যবহার করে মান তুলনা করে । আপনি অবশ্যই একটি নাল মান পাস করতে পারেন এবং কোড কম্পাইল হবে. কিন্তু রানটাইমে আপনি একটি ত্রুটি পাবেন, কারণ পদ্ধতিটি একটি নাল মানতে কল করা হবে, যার ফলে একটি NullPointerException নিক্ষেপ করা হবে।

হ্যাশম্যাপ এবং ট্রিম্যাপের তুলনা

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

সেখানে আপনার কাছে এটি আছে — এখন আপনি জানেন যখন আপনাকে সাজানো ক্রমে মান সংরক্ষণ করতে হবে এবং কীভাবে সাজানোর নিয়ম সেট করতে হবে তখন কী ব্যবহার করতে হবে।