繁体   English   中英

Java中的Treemap的headmap方法

[英]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对象,它们根据其整数优先级值进行比较。 由于bc具有相同的优先级,因此仅将最后一个保存到treeMap 与之相比, abc的优先级低于a且等于b 保留键并替换值。 因此,在映射中将出现一个条目PolicyTypePriorityWrapper b其中包含新替换的值C

这是Map::put(K key, V value)方法的行为。

如果该映射先前包含该键的映射,则旧值将替换为指定值。

现在, NavigableMap::headMap(K toKey, boolean inclusive)返回此地图部分的视图,该视图的键小于(或等于,如果包含,则为true)toKey(从文档中获取)。 结果很明显。 只有ab留在treeMap ,因此a被过滤掉,因为它的优先级比b小,并且只有b可以返回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM