ఒక రోజు యూనివర్సిటీలో, నా క్లాస్‌మేట్స్ చివరి పేర్లను, వారి వ్యక్తిగత డేటాకు కీలుగా పనిచేసిన వాటిని ఆరోహణ క్రమంలో క్రమబద్ధీకరించడానికి నేను కోడ్‌ను వ్రాయవలసి వచ్చింది. నేను దీని కోసం చాలా సమయం వెచ్చించాను. ట్రీమ్యాప్ క్లాస్ గురించి నాకు అప్పటికి తెలిసి ఉంటే , నేను పనిని మరింత వేగంగా పూర్తి చేసి ఉండేవాడిని.

ట్రీమ్యాప్ అంటే ఏమిటి ? ఇది నిఘంటువు-వంటి డేటా నిర్మాణం, ఇది మూలకాలను కీ-విలువ జంటలుగా నిల్వ చేస్తుంది, వాటిని కీ ద్వారా క్రమబద్ధీకరిస్తుంది.

ఎక్కడ మరియు ఎలా ఉపయోగించవచ్చు? సరే, నా క్లాస్‌మేట్స్ చివరి పేర్లతో అదే అసైన్‌మెంట్‌కు ఇది అనువైనదిగా ఉండేది. నేను విలువలను ఆరోహణ క్రమంలో నిల్వ చేయవలసి వస్తే, నా స్వంత సార్టింగ్ అల్గారిథమ్‌ను వ్రాయడానికి బదులుగా, నేను చేయాల్సిందల్లా 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 ఆబ్జెక్ట్‌లను మాత్రమే నిల్వ చేయగలదని గుర్తుంచుకోండి, దీని తరగతి కంపేరబుల్ ఇంటర్‌ఫేస్‌ను అమలు చేస్తుంది మరియు compareTo() పద్ధతిని ఓవర్‌రైడ్ చేస్తుంది.

అయితే మనం వివిధ లైబ్రరీల నుండి లోడ్ చేయబడిన థర్డ్-పార్టీ తరగతులను ఉపయోగిస్తుంటే మరియు వాటిలో పోల్చదగినది అమలు చేయలేకపోతే? దీనికి ఒక పరిష్కారం ఉంది: మీ స్వంత కంపారిటర్‌ని వ్రాయండి .

కంపారేటర్ అనేది కంపేర్ () పద్ధతిని కలిగి ఉన్న ఇంటర్‌ఫేస్. వస్తువులను సరిపోల్చడానికి మరియు వాటిని ట్రీమ్యాప్‌లో నిల్వ చేయడానికి మేము దీన్ని ఉపయోగించవచ్చు.

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లో java.base/java.util.TreeMap.put(TreeMap.java:561)లో మినహాయింపు

సమస్య ఏమిటంటే అంతర్గతంగా ట్రీమ్యాప్ క్లాస్ compareTo() పద్ధతిని ఉపయోగించి విలువలను పోలుస్తుంది . మీరు ఖచ్చితంగా శూన్య విలువలో పాస్ చేయవచ్చు మరియు కోడ్ కంపైల్ అవుతుంది. కానీ రన్‌టైమ్‌లో మీరు ఎర్రర్‌ను పొందుతారు, ఎందుకంటే పద్ధతి శూన్య విలువపై పిలువబడుతుంది , దీని వలన NullPointerException విసిరివేయబడుతుంది.

HashMap మరియు TreeMap పోలిక

TreeMap కాకుండా , HashMap మీరు శూన్యతను కీగా నిల్వ చేయడానికి అనుమతిస్తుంది. నిర్మాణం అన్ని శూన్య కీలకు నిర్దిష్ట స్థలాన్ని కలిగి ఉంది. HashMap శూన్య కీలను నిల్వ చేయగలదు ఎందుకంటే అవి వాటి హాష్ విలువ ఆధారంగా ఎక్కడికి వెళ్తాయో అది నిర్ణయిస్తుంది మరియు హాష్ విలువను లెక్కించడానికి పోలికలు అవసరం లేదు. కాబట్టి అన్ని శూన్య కీలు వాటి స్థానాన్ని కలిగి ఉంటాయి.

అక్కడ మీరు దానిని కలిగి ఉన్నారు - ఇప్పుడు మీరు క్రమబద్ధీకరించబడిన క్రమంలో విలువలను నిల్వ చేయవలసి వచ్చినప్పుడు ఏమి ఉపయోగించాలో మరియు క్రమబద్ధీకరణ కోసం నియమాలను ఎలా సెట్ చేయాలో మీకు తెలుసు.