繁体   English   中英

我们可以为集合算法使用自定义的 equals 方法吗

[英]Can we use custom equals method for Collection Algorithm

我有一个自定义类作为 Student,它有两个不同的 equals 方法(equals、equals1),并且有两个 Student 对象集合作为 list1 和 list2。 当我确实使用 list1.retainAll(list2) 时,需要使用 equals1 机制而不是 eqauls 方法。

这可能吗,或者当我们的客户类中有多个 equals 机制时,我们是否有任何 API 来提及 equals 方法名称。

例子:

class Student {

    public String name;

    public Student(String name) {
        this.name = name;
    }

    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    public boolean equals1(Object obj) {
        if(obj == null) return false;
        if(!(obj instanceof Student)) return false;
        Student student = (Student) obj;
        if(this.name.equals(student.name)) {
            return true;
        } else {
            return false;
        }
    }
}

public class Demo {

    public static void main(String[] args) {

        List<Student> list1 = new ArrayList<Student>();
        list1.add(new Student("AAA"));
        list1.add(new Student("BCD"));

        List<Student> list2 = new ArrayList<Student>();
        list2.add(new Student("AAA"));
        list2.add(new Student("CDE"));

        // Intersection of list1 and list2
        list1.retainAll(list2);

        for (Student student : list1) {
            System.out.println(student.name);
        }
    }
}

如果使用 equals1 方法,则预期结果为 [AAA],但在这种情况下,将执行默认的 equals 方法,因此结果为空。

我们如何使用自定义 equals 方法进行收集算法。

equals()是特殊的

请记住, equals()是特殊的,因为整个集合API 都依赖于它。

此外,集合API(至少任何名称中带有“Hash”的东西,如HashSetHashTable )依赖于equals()hashcode()之间关系:交易是当equals()返回true两个对象都从hashcode()返回相同的值hashcode() . 最重要的是, hashcode()重新调整的值在对象生命周期内不得更改。

您的实现有可能违反此规则,从而迫使集合API zu 失败,因为您的equals1()方法使用可变字段name

您可以创建包装您的实体的 equals 包装器,您的 equals 将类似于:

public class EqulasWrapper<T extends CustomHashCode> {

    T entity;
    BiFunction<T, T, Boolean> customEquals;


    public EqulasWrapper(T entityClass, BiFunction<T, T, Boolean> func){
        this.entity = entityClass;
        this.customEquals = func;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        EqulasWrapper<T> that = (EqulasWrapper<T>) o;
        return this.customEquals.apply(this.entity, that.entity);
    }

    @Override
    public int hashCode() {
        return entity.getCustomHashCode();
    }


    public static class Person implements CustomHashCode {
        private int age;
        private String name;

        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }

        @Override
        public int getCustomHashCode() {
            return age;
        }
    }

    public T getEntity() {
        return entity;
    }

    public BiFunction<T, T, Boolean> getCustomEquals() {
        return customEquals;
    }

    public static void main(String[] args) {
        Person person = new Person(10, "Dan");
        BiFunction<Person, Person, Boolean> myCustomEqualsFunc =
                (p1, p2) -> p1.age == p2.age;

        EqulasWrapper<Person> personEqulasWrapper = new EqulasWrapper<>(person, myCustomEqualsFunc);

        Set<EqulasWrapper> mySet = new HashSet<>();

        mySet.add(personEqulasWrapper);

    }

CustomHashCode 接口如下所示:


public interface CustomHashCode {

    int getCustomHashCode();

}

简短说明

您的集合将使用您的实体实现的自定义哈希代码,并且自定义等于您给他的。

因此您可以使用 EqulasWrapper 类创建不同的集合并设计您的哈希码,并且您的 equals 函数可以满足您的需求,该集合而不是使用原始哈希码和 equals 将与您的包装器一起使用

如果您有任何我想听的问题,希望我能帮上忙。

暂无
暂无

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

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