我有一张类似
的地图 Map<Word, Set<Word>> tupleMap = new HashMap<Word, Set<Word>>();
Word
类没有什么特别之处,它包含一些像value
这样的字符串等等。我试图通过相关集的元素数量对此映射进行排序。所以与大多数单词相关联的单词将在地图中排在第一位。
我确实设法使用以下代码按其密钥对此地图进行排序:
WordMapComparator bvc = new WordMapComparator(tupleMap);
TreeMap<Word, Set<Word>> sortedTupleMap = new TreeMap<Word, Set<Word>>(bvc);
sortedTupleMap.putAll(tupleMap); `
比较器
class WordMapComparator implements Comparator<Word> {
Map<Word, Set<Word>> base;
public WordMapComparator(Map<Word, Set<Word>> tupleMap) {
this.base = tupleMap;
}
public int compare(Word a, Word b) {
return a.getValue().compareTo(b.getValue());
}
}
现在这很好用,因此map会根据words
值进行排序。但是,我尝试了这个比较器:
class WordMapComparator implements Comparator<Word> {
Map<Word, Set<Word>> base;
public WordMapComparator(Map<Word, Set<Word>> tupleMap) {
this.base = tupleMap;
}
public int compare(Word a, Word b) {
return base.get(a).size() >= base.get(b).size() ? -1 : 1;
}
}
并使用
测试生成的地图 1. for(Word w : sortedTupleMap.keySet()){
2. System.out.print(w.getValue() + " : ");
3. for(Word wo : sortedTupleMap.get(w)){
4. System.out.print(wo.getValue() + " ");
5. }
6. System.out.println();
7. }
我在第3行得到null pointer exception
,基本上,结果Set为空。
为什么会发生这种情况,而且,如何解决这个问题?
万分感谢!
答案 0 :(得分:2)
return base.get(a).size() >= base.get(b).size() ? -1 : 1;
这显然是错误的:如果单词的数量相同,它应该返回0,而不是1或-1,具体取决于a和b的比较方式。只需使用
return Integer.compare(base.get(a).size(), base.get(b).size());
然而,这将使地图将所有具有相同数量的相关单词的单词视为相等,因此您需要通过另一个标准来区分它们:
int result = Integer.compare(base.get(a).size(), base.get(b).size());
if (result == 0) {
result = a.compareTo(b);
}
return result;