我有一个自定义类作为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方法进行收集算法。
答案 0 :(得分:1)
equals()
很特别请记住equals()
是特殊的,因为整个 collections API都依赖于它。
此外, collections API(至少具有名称为“ HashSet
或HashTable
的“哈希”的API)依赖于equals()
之间的关系和hashcode()
:交易是equals()
返回true
时,两个对象都从hashcode()
返回相同的值。最重要的是,hashcode()
重调的值在对象生存期内一定不能更改。
由于您的equals1()
方法使用了 mutable 字段name
,因此您的实现有可能违反此规则,导致 collections API失败。
答案 1 :(得分:0)
您可以创建用于包装实体和等价物的等价物包装器 它会像:
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
希望我有所帮助 如果您有任何疑问,我想听听。