简体   繁体   English

Java中的Treemap的headmap方法

[英]Treemap's headmap method in Java

I was checking headMap method of TreeMap which returns a portion of Map whose keys are strictly less than toKey. 我正在检查TreeMap的headMap方法,该方法返回Map的一部分,其键严格小于toKey。 So I was expecting output to be B, C but it returns only B. Here is a thing I did weird I changed compareTo method like this return this.priority > o.priority ? 1 : -1; 因此,我期望输出为B,C,但它仅返回B。这是我做的一件很奇怪的事情,我改变了compareTo方法,就像这样return this.priority > o.priority ? 1 : -1; return this.priority > o.priority ? 1 : -1; then it started returning C, B which is I was expecting. 然后它开始返回C,B,这正是我所期望的。 I am sure this is not correct but how can I get both B, C which has lower priority than A. Where I am getting it wrong. 我确定这是不正确的,但是我如何才能得到优先级低于A的B,C。我在哪里弄错了。 Thanks. 谢谢。

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 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);
    }
}

That's because you are not following JDK documentation guidelines, from Comprarable : 那是因为您没有遵循Comprarable JDK文档指南:

It is strongly recommended (though not required) that natural orderings be consistent with equals. 强烈建议(尽管不是必需的)自然顺序应与等号保持一致。 This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. 之所以如此,是因为没有显式比较器的排序集(和排序映射)与自然排序与等式不一致的元素(或键)一起使用时,其行为“奇怪”。 In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method. 特别是,这样的排序集(或排序图)违反了根据equals方法定义的集合(或图)的一般约定。

As you can see you have circumstances in which a.compareTo(b) == 0 but !a.equals(b) . 如您所见,在某些情况下a.compareTo(b) == 0!a.equals(b) Both "B", 1 and "C", 1 are considered equal for the TreeMap : 对于TreeMap "B", 1"C", 1均被视为相等:

Note that the ordering maintained by a tree map, like any sorted map, and whether or not an explicit comparator is provided, must be consistent with equals if this sorted map is to correctly implement the Map interface. 请注意,如果树排序图要正确实现Map接口,则树映射所维护的排序(与任何排序的映射一样)以及是否提供显式比较器必须与equals一致。 (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Map interface is defined in terms of the equals operation, 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 . (有关与equals一致的精确定义,请参见Comparable或Comparator。)之所以这样,是因为Map接口是根据equals操作定义的, 但是排序后的map使用其compareTo (或compare)方法执行所有键比较,因此两个从已排序映射的角度来看,此方法认为相等的键是equal The behavior of a sorted map is well-defined even if its ordering is inconsistent with equals; 排序后的映射的行为是明确定义的,即使其排序与equals不一致也是如此; it just fails to obey the general contract of the Map interface. 它只是不遵守Map接口的一般约定。

For example, if one adds two keys a and b such that (!a.equals(b) && a.compareTo(b) == 0) to a sorted set that does not use an explicit comparator, the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective . 例如,如果将两个键a和b相加,使得(!a.equals(b) && a.compareTo(b) == 0)到不使用显式比较器的排序集中, 则第二个add操作返回false (而且排序集的大小不会增加),因为从排序集的角度来看,a和b是等效的

So what happens is that you compareTo is not able to distinguish two elements with same priority but different type, but since a TreeMap is using ONLY that method to decide if two elments are equal then you are not adding them both to the map in the first place. 所以会发生什么是你compareTo无法区分具有相同的优先级,但不同类型的两个元素,但由于一个TreeMap 使用该方法来决定如果两个elments是相等的,那么你是不是他们俩在第一添加到地图地点。

Did you try if treeMap.size() == 3 ? 您是否尝试过treeMap.size() == 3 My guess is that it's 2 in the first place. 我的猜测是,它首先是2。

The new PolicyTypePriorityWrapper("B", 1) is not qualified because it does it even not make it into the treeMap . new PolicyTypePriorityWrapper("B", 1)不合格,因为它甚至没有将其放入treeMap

Why? 为什么? Because the keys are the PolicyTypePriorityWrapper objects which are compared according to their integer priority value. 因为键是PolicyTypePriorityWrapper对象,它们根据其整数优先级值进行比较。 Since b and c have the same priority, only the last one is saved to the treeMap . 由于bc具有相同的优先级,因此仅将最后一个保存到treeMap Compared a , b and c has a lower priority than a and equal to b . 与之相比, abc的优先级低于a且等于b The key remains and the value is replaced. 保留键并替换值。 So in the map appears an entry PolicyTypePriorityWrapper b with the newly replaced value C . 因此,在映射中将出现一个条目PolicyTypePriorityWrapper b其中包含新替换的值C

It's the behavior of Map::put(K key, V value) method. 这是Map::put(K key, V value)方法的行为。

If the map previously contained a mapping for the key, the old value is replaced by the specified value. 如果该映射先前包含该键的映射,则旧值将替换为指定值。

Now the NavigableMap::headMap(K toKey, boolean inclusive) which returns a view of the portion of this map whose keys are less than (or equal to, if inclusive is true) toKey (taken from the documentation). 现在, NavigableMap::headMap(K toKey, boolean inclusive)返回此地图部分的视图,该视图的键小于(或等于,如果包含,则为true)toKey(从文档中获取)。 The result is obvious. 结果很明显。 Only a and b stay in the treeMap , so the a is filtered out since it has smaller priority to b and only b is qualified to be returned. 只有ab留在treeMap ,因此a被过滤掉,因为它的优先级比b小,并且只有b可以返回。

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

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