[英]Treemap's headmap method in Java
我正在检查TreeMap的headMap方法,该方法返回Map的一部分,其键严格小于toKey。 因此,我期望输出为B,C,但它仅返回B。这是我做的一件很奇怪的事情,我改变了compareTo方法,就像这样return this.priority > o.priority ? 1 : -1;
return this.priority > o.priority ? 1 : -1;
然后它开始返回C,B,这正是我所期望的。 我确定这是不正确的,但是我如何才能得到优先级低于A的B,C。我在哪里弄错了。 谢谢。
NavigableMap<PolicyTypePriorityWrapper, String> treeMap = new TreeMap();
PolicyTypePriorityWrapper a = new PolicyTypePriorityWrapper("A", 2);
PolicyTypePriorityWrapper b = new PolicyTypePriorityWrapper("B", 1);
PolicyTypePriorityWrapper c = new PolicyTypePriorityWrapper("C", 1);
treeMap.put(a, "A");
treeMap.put(b, "B");
treeMap.put(c, "C");
NavigableMap<PolicyTypePriorityWrapper, String> map = treeMap.headMap(a, false);
Set<PolicyTypePriorityWrapper> policyTypePriorityWrappers = map.keySet();
for (PolicyTypePriorityWrapper pol: policyTypePriorityWrappers) {
System.out.println(pol.getPolicyType());
}
PolicyTypePriorityWrapper.java
class PolicyTypePriorityWrapper implements Comparable<PolicyTypePriorityWrapper> {
private String policyType;
private int priority;
public PolicyTypePriorityWrapper(final String policyType, final int priority) {
this.policyType = policyType;
this.priority = priority;
}
public String getPolicyType() {
return this.policyType;
}
public int getPriority() {
return this.priority;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PolicyTypePriorityWrapper that = (PolicyTypePriorityWrapper) o;
if (priority != that.priority) return false;
return policyType.equals(that.policyType);
}
@Override
public int hashCode() {
int result = policyType.hashCode();
result = 31 * result + priority;
return result;
}
@Override
public int compareTo(final PolicyTypePriorityWrapper o) {
return Integer.compare(this.priority, o.priority);
}
}
那是因为您没有遵循Comprarable
JDK文档指南:
强烈建议(尽管不是必需的)自然顺序应与等号保持一致。 之所以如此,是因为没有显式比较器的排序集(和排序映射)与自然排序与等式不一致的元素(或键)一起使用时,其行为“奇怪”。 特别是,这样的排序集(或排序图)违反了根据equals方法定义的集合(或图)的一般约定。
如您所见,在某些情况下a.compareTo(b) == 0
但!a.equals(b)
。 对于TreeMap
"B", 1
和"C", 1
均被视为相等:
请注意,如果树排序图要正确实现
Map
接口,则树映射所维护的排序(与任何排序的映射一样)以及是否提供显式比较器必须与equals一致。 (有关与equals一致的精确定义,请参见Comparable或Comparator。)之所以这样,是因为Map
接口是根据equals操作定义的, 但是排序后的map使用其compareTo
(或compare)方法执行所有键比较,因此两个从已排序映射的角度来看,此方法认为相等的键是equal 。 排序后的映射的行为是明确定义的,即使其排序与equals不一致也是如此; 它只是不遵守Map接口的一般约定。例如,如果将两个键a和b相加,使得
(!a.equals(b) && a.compareTo(b) == 0)
到不使用显式比较器的排序集中, 则第二个add操作返回false (而且排序集的大小不会增加),因为从排序集的角度来看,a和b是等效的 。
所以会发生什么是你compareTo
无法区分具有相同的优先级,但不同类型的两个元素,但由于一个TreeMap 仅使用该方法来决定如果两个elments是相等的,那么你是不是他们俩在第一添加到地图地点。
您是否尝试过treeMap.size() == 3
? 我的猜测是,它首先是2。
new PolicyTypePriorityWrapper("B", 1)
不合格,因为它甚至没有将其放入treeMap
。
为什么? 因为键是PolicyTypePriorityWrapper
对象,它们根据其整数优先级值进行比较。 由于b
和c
具有相同的优先级,因此仅将最后一个保存到treeMap
。 与之相比, a
, b
和c
的优先级低于a
且等于b
。 保留键并替换值。 因此,在映射中将出现一个条目PolicyTypePriorityWrapper b
其中包含新替换的值C
这是Map::put(K key, V value)
方法的行为。
如果该映射先前包含该键的映射,则旧值将替换为指定值。
现在, NavigableMap::headMap(K toKey, boolean inclusive)
返回此地图部分的视图,该视图的键小于(或等于,如果包含,则为true)toKey(从文档中获取)。 结果很明显。 只有a
和b
留在treeMap
,因此a
被过滤掉,因为它的优先级比b
小,并且只有b
可以返回。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.