如何使用自定义比较器或equals方法查找“设置差异"? [英] How to find Set difference with custom Comparator or equals method?
问题描述
我想使用与类 T
所使用的度量不同的相等度量来找到两个 Set< T>
之间的差异,例如自定义的 Comparator< T>
I want to find the difference between two Set<T>
using a different equality metric than that used by the class T
, for example a custom Comparator<T>
例如,我有一个 Animal
类,通常使用 Animal
For example, I have a class Animal
, which usually tests equality using the species of the Animal
public class Animal {
public String species;
public String genus;
public Animal(String species, String genus){
this.species = species;
this.genus = genus;
}
public boolean equals(Animal other){
return other.species.equals(this.species);
}
}
我有两个 List< Animal>
,我想找到两个列表之间共享属的交集.
I have two List<Animal>
and I'd like to find the intersection of shared genus between the two lists.
Usually, I'd convert the List
to Set
and use retainAll
to find the intersection. But here, that would give the intersection of shared species, not shared genus.
我想使用 GenusComparator
之类的东西来定义交集的相等性.
I'd like to use something like the GenusComparator
to define equality for the intersection.
public class GenusComparator implements Comparator<Animal>{
@Override
public int compare(Animal animal1, Animal animal2) {
return String.CASE_INSENSITIVE_ORDER.compare(animal1.genus, animal2.genus);
}
}
这只是一个简单的示例,用于解释我要执行的操作,而不是应用程序中的实际类.
This is just a simple example to explain what I'm trying to do, not the actual classes in my application.
我发现了两个可能的解决方案
Two possible solutions that I have found are
- 包装类并覆盖equals方法
- 使用
TreeSet
与自定义比较器
到目前为止,我是否还错过了其他方法,这些解决方案可能有哪些利弊?
Are there other ways I've missed so far, and what are the possible pros and cons of these solutions?
推荐答案
最简单的方法是简单地将 TreeSet
与 GenusComparator
一起使用.
The easiest way to do it, is to simple use a TreeSet
with the GenusComparator
.
您必须将这两个集合都转换为 TreeSet(GenusComparator)
,以使 retainAll()
正常工作.
You have to convert both sets to TreeSet(GenusComparator)
for the retainAll()
to work correctly.
我修复了 equals()
并添加了 hashCode()
和 toString()
.
public class Test {
public static void main(String[] args) {
Set<Animal> set1 = new HashSet<>(Arrays.asList(new Animal("Jaguar", "Panthera"),
new Animal("Margay", "Leopardus"),
new Animal("Tiger", "Panthera")));
Set<Animal> set2 = new HashSet<>(Arrays.asList(new Animal("Bobcat", "Lynx"),
new Animal("Cougar", "Puma"),
new Animal("Leopard", "Panthera")));
TreeSet<Animal> treeSet1 = new TreeSet<>(new GenusComparator());
treeSet1.addAll(set1);
TreeSet<Animal> treeSet2 = new TreeSet<>(new GenusComparator());
treeSet2.addAll(set2);
treeSet1.retainAll(treeSet2);
System.out.println(treeSet1);
}
}
class Animal {
public String species;
public String genus;
public Animal(String species, String genus) {
this.species = species;
this.genus = genus;
}
@Override
public boolean equals(Object obj) {
return obj instanceof Animal && this.species.equals(((Animal)obj).species);
}
@Override
public int hashCode() {
return this.species.hashCode();
}
@Override
public String toString() {
return this.species + "/" + this.genus;
}
}
class GenusComparator implements Comparator<Animal> {
@Override
public int compare(Animal animal1, Animal animal2) {
return String.CASE_INSENSITIVE_ORDER.compare(animal1.genus, animal2.genus);
}
}
输出
[Jaguar/Panthera]
这篇关于如何使用自定义比较器或equals方法查找“设置差异"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!