问题
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