首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TreeSet等于另一个TreeSet

TreeSet等于另一个TreeSet
EN

Stack Overflow用户
提问于 2019-02-08 12:14:21
回答 3查看 236关注 0票数 1

如何确定两个TreeSet对象是否相等?我使用OpenJDK-10

ModifiebleObject

代码语言:javascript
复制
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);
    }
}

SomeCode

代码语言:javascript
复制
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 (元素实现可比较)。

有趣,但JavaDoc撒谎了!

java.utilTreeSet

代码语言:javascript
复制
/**
 * 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 true}当且仅当此集合包含一个元素{@代码e},使得{@code Objects.equals(o,e)}。

但实际上它使用的是compareTo

更新

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

EN

回答 3

Stack Overflow用户

发布于 2019-02-08 12:24:43

TreeSet明确指出了这一点。这不是什么阴谋。

注意,如果要正确实现set接口,由一个集合(无论是否提供显式比较器)维护的排序必须与等于一致。(与平等一致的精确定义见可比或比较器)。这是因为set接口是按照等于操作定义的,但是一个TreeSet实例使用它的compareTo (或compare)方法执行所有元素比较,因此从Set的角度来看,这个方法认为相等的两个元素是相等的。一个集合的行为是明确的,即使它的顺序与相等不一致;它只是没有遵守set接口的一般契约。

你的班级忽视了Comparable,而你正在为此付出代价。

强烈建议使用(x.compareTo(y)==0) == (x.equals(y)),但不是严格要求

票数 2
EN

Stack Overflow用户

发布于 2019-02-08 12:28:45

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

代码语言:javascript
复制
 org.apache.commons.collections
 SetUtils.isEqualSet(set1, set2);

代码语言:javascript
复制
 org.apache.commons.collections
 CollectionUtils.isEqualCollection(a, b)
票数 2
EN

Stack Overflow用户

发布于 2019-02-12 19:02:04

这是一个对我有效的解决方案。

代码语言:javascript
复制
class TreeSetWithEquals extends TreeSet {

    //Constructors which I will use
    //

    // I consider two sets equal if they have equal elements in the same order!
    @Override
    public boolean equals(Object o) {
        //Check if Object not null, not the same reference as this, and 
        // it is instance of Set
        //And their sizes are equal
        //Iterate through boths sets and apply equals for each method.
    }
}

我为什么要这么做?在我们的代码中,我们为Idea ->中使用Objects.equals(this.field_i, that.field_i)的其他对象生成相等。我们懒得搜索代码中的位置并替换Objects.equals(this.field_i, that.field_i),如果field_i是一个排序集,则为一个util类,以检查集合的相等性。因此,更容易使用支持排序的集合,但对于this.equals中的每个元素使用this.equals

有些人告诉我,eqaulshashCodecompareTo必须是一致的。我同意eqauls的观点,hashCode必须是一致的。

例如。

代码语言:javascript
复制
enum WeaponType {

     KNIFE,
     HAND_GUN,
     TWO_HANDED_GUN,
     GRANADES, //To allow flash, smoke and fragmentation granades
     DEFUSE_KIT
}

class Shooter {

    // make sure we can have different weapons,
    // but only one of type is allowed.
    // Our tree set with such comparator will guarantee this requirement.
    private SortedSet<Weapon> weapons = buyWeapons(andUseWeaponTypeComparator);

为此,我将定义一个WeaponComparator

代码语言:javascript
复制
Comparator<Weapon> WEAPON_COMPARATOR = Compareator
       .comparing(Weapon::getType, Comparator.naturalOrder()) //enum uses its element order.
}

现在,如果你想持久化一个枪手并在卡夫卡向其他微服务发送消息,你将有equals来检查who send实体。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54592253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档