所以我有一个非常奇怪的错误.当我最初使用keySet()迭代大型TreeMap的前10个键时,我偶然发现了它.其中一个键是返回null,就我的理解而言,这是不可能的.所以我在下面写了测试代码:
int i = 0;
for (Map.Entry<String, Integer> es : sortedMap.entrySet()){
if (i >= 10) {
break;
}
if (sortedMap.containsKey(es.getKey())){
System.out.println(es.getKey() + ":" + sortedMap.get(es.getKey()));
} else {
System.out.println("Key " + es.getKey() + " does not exist, yet...");
System.out.println("This does work: " + es.getKey() + ":" + es.getValue());
System.out.println("This does NOT work: " + es.getKey() + ":" + sortedMap.get(es.getKey()));
}
i++;
}
Run Code Online (Sandbox Code Playgroud)
并获得以下结果:
SOAP:967
'excerpt'::679
'type'::679
Key 'author_url': does not exist, yet...
This does work: 'author_url'::679
This does NOT work: 'author_url'::null
'date'::679
Android:437
TLS:295
message:283
server:230
monthly:215
<<<<<<<<<<<<<<<<<<<<DUMPING MAP!
{SOAP=967, 'excerpt':=679, 'type':=679, 'author_url':=679, 'date':=679, Android=437, TLS=295, message=283, server=230, monthly=215...
Run Code Online (Sandbox Code Playgroud)
我在前十名之后切断了地图,因为那里有更多,但所有这些都是一个有价值的钥匙.
所以我的问题是这样的:当我使用密钥从TreeMap直接获取(key)时,为什么我得到null,但是EntrySet返回正确的键和值?
这是我的比较器,因为我在Integer上订购:
class ValueComparator implements Comparator<Object> {
Map<String, Integer> base;
public ValueComparator(Map<String, Integer> base) {
this.base = base;
}
public int compare(Object a, Object b) {
if ((Integer) base.get(a) < (Integer) base.get(b)) {
return 1;
} else if ((Integer) base.get(a) == (Integer) base.get(b)) {
return 0;
} else {
return -1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
TreeMap的构建如下:
ValueComparator bvc = new ValueComparator(allMatches);
TreeMap<String, Integer> sortedMap = new TreeMap<String, Integer>(bvc);
//Sort the HashMap
sortedMap.putAll(allMatches);
Run Code Online (Sandbox Code Playgroud)
allMatches是一个 HashMap<String, Integer>
从您的TreeMap节目的迭代顺序来看,绝对是您使用自定义的情况Comparator.[否则迭代将按字典顺序排列]
请注意,根据javadocs:
实现者必须确保所有x和y的sgn(compare(x,y))== -sgn(compare(y,x)).(这意味着当且仅当compare(y,x)抛出异常时,compare(x,y)必须抛出异常.)
实现者还必须确保关系是传递的:((compare(x,y)> 0)&&(compare(y,z)> 0))表示compare(x,z)> 0.
最后,实现者必须确保compare(x,y)== 0意味着所有z的sgn(compare(x,z))== sgn(compare(y,z)).
如果您Comparator不应用这些规则 - 行为未定义,可能会显示奇怪的结果 - 如您所见.
编辑: [作为对编辑问题的回复]
您的隔离专区使用标识[ operator==]来检查两个整数.
请注意,这Integer是一个对象 - 因此只有在它是同一个对象时operator==才会返回true.
你应该equals()用来检查两个整数是否相同 - 甚至更好 - 使用Integer.compareTo()
问题解决了:
class ValueComparator implements Comparator<Object> {
Map<String, Integer> base;
public ValueComparator(Map<String, Integer> base) {
this.base = base;
}
public int compare(Object a, Object b) {
if (((Integer) base.get(a)).intValue() < ((Integer) base.get(b)).intValue()) {
return 1;
} else if ( ((Integer) base.get(a)).intValue() == ((Integer) base.get(b)).intValue()) {
return ((String)a).compareTo(((String)b));
} else {
return -1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这带来了额外的好处,即按字母顺序带回具有相同值的键。
| 归档时间: |
|
| 查看次数: |
7909 次 |
| 最近记录: |