equals和contains方法之间有什么区别

JPG*_*JPG 1 java collections treeset

我正在使用TreeSet以下代码处理该集合:

import java.util.*;
public class Employee implements Comparable<Employee>{

    private int ID;

    public Employee(int iD) {
        ID = iD;
    }

    @Override
    public int compareTo(Employee obj) {
        return this.ID-obj.ID;
    }

    private static void intoTreeSet() {
        Employee e1=new Employee(4);
        Employee e2=new Employee(2);
        Employee e3=new Employee(1);
        Employee e4=new Employee(5);
        Employee e5=new Employee(3);

        Employee eTemp=new Employee(3);

        Set<Employee> set=new TreeSet();
        set.add(e1);set.add(e2);set.add(e3);set.add(e4);set.add(e5);

        System.out.println("output says: ");
        for(Employee e:set){
            System.out.print(e.ID+" ~ ");
        }
        System.out.println();
        if(set.contains(eTemp)){
            System.out.println("C O N T A I N S !!!");
        }

        if(e5.equals(eTemp)){
            System.out.println("E Q U A L S !!!");
        }
    }

    public static void main(String[] args) {
        intoTreeSet();
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

output says: 
1 ~ 2 ~ 3 ~ 4 ~ 5 ~ 
C O N T A I N S !!!
Run Code Online (Sandbox Code Playgroud)

我很困惑看到输出.我想知道,如果它没有通过equals案例,那么它如何通过contains案例.

我知道如果两个对象的类重写equals方法并且根据某些属性它们是相等的,那么它们只能是相等的.我故意没有覆盖equals方法来看看如何contains工作.如果它是一个非基于树的集合,我们可以说它ArrayList不会通过contains测试.为什么会这样?任何人都可以解释这种行为并清除我的困惑.

ska*_*man 6

javadocjava.util.TreeSet说:

请注意,如果要正确实现Set接口,则由set维护的排序(无论是否提供显式比较器)必须与equals一致.(有关与equals一致的精确定义,请参阅Comparable或Comparator.)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用compareTo(或compare)方法执行所有元素比较,因此从集合的角度来看,通过这种方法被认为相等的元素是相等的.集合的行为即使其排序与equals不一致也是明确定义的; 它只是不遵守Set接口的一般合同.

换句话说,实现compareTo并且equals必须彼此一致.如果他们不是,那么行为TreeSet将是不稳定的.它可能有效,但可能没有.要了解它何时发生以及何时不发生,您需要仔细查看TreeSet实现,但由于javadoc在TreeSet工作条件非常明确,因此尝试颠覆它并不是一个好主意.