首页 > 解决方案 > TreeSet 等于另一个 TreeSet

问题描述

如何判断两个TreeSet对象是否相等?我使用open-jdk-10

可修改对象

class ModifiebleObject implements Comparable<ModifiebleObject>{

    Integer number;
    String text;

    @Override
    public int compareTo(final ModifiebleObject o) {
        return this.number - o.number;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (!(o instanceof ModifiebleObject)) return false;
        final ModifiebleObject that = (ModifiebleObject) o;
        return Objects.equals(number, that.number) &&
                Objects.equals(text, that.text);
    }

    @Override
    public int hashCode() {
        return Objects.hash(number, text);
    }
}

一些代码

SortedSet<ModifiebleObject> tree1 = prepare();
SortedSet<ModifiebleObject> tree2 = prepare(); //Returns cloned elements, so object references in tree1 and tree2 are different.

// ModifiebleObject implements Comparable<ModifiebleObject>
// compareTo does not use all the fields, just some of them.
//setSomeValueOutsideOfComparable sets value of the field, which is not used by compareTo
tree2.first().setSomeValueOutsideOfComparable("newValue");

boolean tree1EqualsTree2 = tree1.equals(tree2); //Returns true

因为

TreeSet 调用AbstractSet.containsAll-> TreeSet.contains-> TreeMap.containsKey->TreeMap.getEntry != null

TreeMap.getEntry使用压缩器或元素 compareTo(元素实现 Comparable)。

有趣,但 JavaDoc 撒谎!

java.utilTreeSet

/**
 * Returns {@code true} if this set contains the specified element.
 * More formally, returns {@code true} if and only if this set
 * contains an element {@code e} such that
 * {@code Objects.equals(o, e)}.
 *
 * @param o object to be checked for containment in this set
 * @return {@code true} if this set contains the specified element
 * @throws ClassCastException if the specified object cannot be compared
 *         with the elements currently in the set
 * @throws NullPointerException if the specified element is null
 *         and this set uses natural ordering, or its comparator
 *         does not permit null elements
 */
public boolean contains(Object o) {
    return m.containsKey(o);
}

更正式地说,当且仅当这个集合包含一个元素 {@code e} 使得 {@code Objects.equals(o, e)} 时才返回 {@code true}。

但实际上它使用compareTo.


更新

我可以使用来自 jdk 或其他库的其他集合来保证唯一元素并排序,并且等于另一个集合用于每个元素 equals。

标签: javacollectionstreeset

解决方案


如果您有一组定义的对象,那么您可以覆盖哈希码和等于方法以及基于哈希码和等于方法的以下方法比较。您可以使用

 org.apache.commons.collections
 SetUtils.isEqualSet(set1, set2);

或者

 org.apache.commons.collections
 CollectionUtils.isEqualCollection(a, b)

推荐阅读