TreeMap.get() return Null even key exists

故事扮演 提交于 2019-12-02 07:39:00

问题


I am trying to get from TreeMap but it return null even the key exist. HashCode and eqauls is based on word only. Comparable is based on freqency.

    public static void main(){
        TreeMap<Word,Integer> test = new TreeMap<>();
        test.put(new Word("pqr",12),1);
        test.put(new Word("abc",2),1);

        Integer prq = test.get(new Word("pqr",1));
        System.out.println(prq);
        prq = test.get(new Word("pqr",12));
        System.out.println(prq);
    }


    public class Word implements Comparable<Word>{
        String word;
        Integer freq;

        public Word(String word, Integer freq) {
            this.word = word;
            this.freq = freq;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Word)) return false;

            Word word1 = (Word) o;

            return word.equals(word1.word);
        }

        @Override
        public int hashCode() {
            return word.hashCode();
        }


        @Override
        public int compareTo(Word o) {
            return this.freq.compareTo(o.freq);
        }
    }

Output is like null 1


回答1:


TreeMap uses the compareTo method to decide key ordering and key equality.

Since your Word class uses the freq field in its compareTo method, any two Words with the same freq are considered equal.

From the documentation of TreeMap:

... but a sorted map performs all key comparisons using its compareTo (or compare) method, so two keys that are deemed equal by this method are, from the standpoint of the sorted map, equal.




回答2:


In your compareTo method it is comparing the frequency. So if the frequency is same it will be equal.

to compare the words you can use

return this.word.compareTo(o.word);

or to compare both word and frequency you can use

return this.word.compareTo((o.word)) *  this.freq.compareTo(o.freq);

EDIT

Now as you need to sort using the frequency so instead of using comparable you can use Comparator. Use the above comparators to create the Map. And use your previous comprator to sort.

while creating

        TreeMap<Word, Integer> test = new TreeMap<Word, Integer>(
            new Comparator<Word>() {
                public int compare(Word word, Word o) {
                    return word.word.compareTo((o.word));
                }
            });

and while sorting

    Collections.sort(new LinkedList(test.keySet()), new Comparator<Word>() {
        public int compare(Word word, Word o) {
            return word.freq.compareTo((o.freq));
        }
    });



回答3:


This is what exactly happen in the TreeMpa.get() method,

while (p != null) {
            int cmp = k.compareTo(p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }

TreeMpa use compareTo method to find the value. so it will loop through all the item till k.compareTo(p.key) return 0




回答4:


this code here is not working if the class word don't override properly Equals and hashcode...

TreeMap<Word,Integer> test = new TreeMap<>();
test.put(new Word("pqr",12),1);
test.put(new Word("abc",2),1);

Integer prq = test.get(new Word("pqr",1));
System.out.println(prq);
prq = test.get(new Word("pqr",12));



回答5:


Since your Word class implements Comparable interface . So TreeMap uses compareTo method for comparing properties of objects.

If you want to get the object with same String "word" then implement compareTo method like

@Override
public int compareTo(Word o) {
    return this.word.compareTo(o.word);
}


来源:https://stackoverflow.com/questions/43245952/treemap-get-return-null-even-key-exists

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!