பல்கலைக்கழகத்தில் ஒரு நாள், எனது வகுப்புத் தோழர்களின் கடைசிப் பெயர்களை, அவர்களின் தனிப்பட்ட தரவுகளின் சாவியாக, ஏறுவரிசையில் வரிசைப்படுத்த, குறியீட்டை எழுத வேண்டியிருந்தது. இதற்காக நிறைய நேரம் செலவிட்டேன். ஆனால் அப்போது ட்ரீமேப் வகுப்பைப் பற்றி எனக்குத் தெரிந்திருந்தால் , பணியை மிக வேகமாக முடித்திருப்பேன்.

ட்ரீமேப் என்றால் என்ன ? இது ஒரு அகராதி போன்ற தரவு அமைப்பாகும், இது உறுப்புகளை ஒரு முக்கிய மதிப்பு ஜோடிகளாக சேமித்து, அவற்றை விசையால் வரிசைப்படுத்துகிறது.

எங்கே, எப்படிப் பயன்படுத்தலாம்? சரி, எனது வகுப்புத் தோழர்களின் கடைசிப் பெயர்களுடன் அதே பணிக்கு ஏற்றதாக இருந்திருக்கும். நான் மதிப்புகளை ஏறுவரிசையில் சேமிக்க வேண்டும் என்றால், என்னுடைய சொந்த வரிசையாக்க அல்காரிதத்தை எழுதுவதற்குப் பதிலாக, நான் செய்ய வேண்டியது 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 வகுப்பு NavigableMap இடைமுகத்தை செயல்படுத்துகிறது , இது வரிசைப்படுத்தப்பட்ட வரைபட இடைமுகத்தை நீட்டிக்கிறது . இது TreeMap வகுப்பை வரிசைப்படுத்தப்பட்ட வரிசையில் மதிப்புகளைச் சேமிக்க மரங்களைப் பயன்படுத்த அனுமதிக்கிறது.

விக்கிபீடியா சொல்வது போல், மரம் என்பது சுய-சமநிலை பைனரி தேடல் அமைப்பாகும், இது முதலில் மதிப்புகளை ஒப்பிட்டுப் பார்த்த பிறகு அதன் முனைகளில் தரவைச் சேமிக்கிறது.

எளிமையாகச் சொல்வதானால், சிவப்பு-கருப்பு மரம் என்பது ஒரு தரவு கட்டமைப்பாகும், இது ரூட்டை விட பெரியதாக இருந்தால் வலது சப்ட்ரீயிலும், அவை குறைவாக இருந்தால் இடது சப்ட்ரீயிலும் சேமிக்கும். இந்த செயல்படுத்தல் கட்டமைப்பில் உள்ள மதிப்புகளை மிக விரைவாக பார்க்க முடியும்.

சிவப்பு-கருப்பு மரம் சுய-சமநிலைப்படுத்துகிறது, எனவே ஒவ்வொரு புதிய மதிப்பு செருகப்படும்போதும் அதன் கட்டமைப்பை மாற்றுகிறது. முதலில் சேர்க்கப்பட்ட மதிப்பு முதலில் ரூட்டாகக் கருதப்படுகிறது, ஆனால் சமநிலைச் செயல்பாட்டின் போது மற்றொரு மதிப்பு ரூட்டாக மாறும்.

சரி, TreeMap என்றால் என்ன, அது எப்படி வேலை செய்கிறது என்பது இப்போது உங்களுக்குத் தெரியும்.

TreeMap, Comparable interface ஐ செயல்படுத்தும் மற்றும் compareTo() முறையை மீறும் பொருட்களை மட்டுமே சேமிக்க முடியும் என்பதை நினைவில் கொள்ளவும் .

ஆனால், பல்வேறு நூலகங்களில் இருந்து ஏற்றப்பட்ட மூன்றாம் தரப்பு வகுப்புகளைப் பயன்படுத்தினால், அவற்றில் ஒப்பிடக்கூடியவற்றைச் செயல்படுத்த முடியாவிட்டால் என்ன செய்வது? இதற்கு ஒரு தீர்வு உள்ளது: உங்கள் சொந்த ஒப்பீட்டாளரை எழுதுங்கள் .

ஒப்பீட்டாளர் என்பது ஒப்பீட்டு () முறையைக் கொண்ட ஒரு இடைமுகம். நாம் பொருட்களை ஒப்பிட்டு அவற்றை ஒரு 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 இல் மதிப்புகளைச் சேமிக்க , அவற்றை எவ்வாறு வரிசைப்படுத்துவது என்பதை நீங்கள் குறிப்பிட வேண்டும். இதைச் செய்ய இரண்டு வழிகள் உள்ளன: ஒப்பிடக்கூடியவை அல்லது உங்கள் சொந்த ஒப்பீட்டாளரைச் செயல்படுத்தவும் .

ஆனால் ட்ரீமேப்பில் பூஜ்யத்தை ஒரு விசையாக வைக்க வேண்டுமானால் என்ன செய்வது ? இதைச் செய்ய HashMap உங்களை அனுமதிக்கிறது. ஆம், ஆனால் TreeMap இதை எவ்வாறு கையாள்கிறது?

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

இந்தக் குறியீட்டை இயக்குவது பிழையை ஏற்படுத்துகிறது:

நூல் "முக்கிய" java.lang இல் விதிவிலக்கு.NullPointerException at java.base/java.util.TreeMap.put(TreeMap.java:561)

பிரச்சனை என்னவென்றால், உள்நாட்டில் TreeMap வகுப்பு compareTo() முறையைப் பயன்படுத்தி மதிப்புகளை ஒப்பிடுகிறது . நீங்கள் நிச்சயமாக ஒரு பூஜ்ய மதிப்பை அனுப்பலாம் மற்றும் குறியீடு தொகுக்கப்படும். ஆனால் இயக்க நேரத்தில் நீங்கள் ஒரு பிழையைப் பெறுவீர்கள், ஏனெனில் முறை பூஜ்ய மதிப்பில் அழைக்கப்படும் , இதனால் NullPointerException எறியப்படும்.

HashMap மற்றும் TreeMap ஒப்பீடு

TreeMap போலல்லாமல் , HashMap பூஜ்யத்தை ஒரு திறவுகோலாக சேமிக்க உங்களை அனுமதிக்கிறது . அனைத்து பூஜ்ய விசைகளுக்கும் கட்டமைப்பில் ஒரு குறிப்பிட்ட இடம் உள்ளது . ஹாஷ்மேப் பூஜ்ய விசைகளை சேமிக்க முடியும், ஏனெனில் அவை ஹாஷ் மதிப்பின் அடிப்படையில் அவை எங்கு செல்கின்றன என்பதை இது தீர்மானிக்கிறது, மேலும் ஹாஷ் மதிப்பைக் கணக்கிடுவதற்கு ஒப்பீடுகள் தேவையில்லை. எனவே அனைத்து பூஜ்ய விசைகளும் அவற்றின் இடத்தைப் பெற்றுள்ளன.

உங்களிடம் உள்ளது - வரிசைப்படுத்தப்பட்ட வரிசையில் மதிப்புகளைச் சேமிக்க வேண்டியிருக்கும் போது எதைப் பயன்படுத்த வேண்டும் மற்றும் வரிசைப்படுத்துவதற்கான விதிகளை எவ்வாறு அமைப்பது என்பது இப்போது உங்களுக்குத் தெரியும்.