有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用自定义比较器equals方法查找集合差异?

我想使用不同于类T使用的相等度量来查找两个Set<T>之间的差异,例如自定义Comparator<T>

例如,我有一个类Animal,它通常使用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>,我想找到两个列表之间共享属的交集

通常,我会将List转换为Set,并使用^{}查找交点。但在这里,这将给出共享物种的交叉点,而不是共享属

我想使用类似GenusComparator的东西来定义交叉点的相等性

public class GenusComparator implements Comparator<Animal>{

    @Override
    public int compare(Animal animal1, Animal animal2) {
        return String.CASE_INSENSITIVE_ORDER.compare(animal1.genus, animal2.genus);
    }

}

这只是一个简单的例子来解释我试图做什么,而不是我的应用程序中的实际类

我发现了两种可能的解决方案:

  1. 包装该类并重写equals方法
  2. ^{}与自定义比较器一起使用

到目前为止,我是否还错过了其他方法,这些解决方案可能有哪些优点和缺点


共 (1) 个答案

  1. # 1 楼答案

    最简单的方法是将TreeSetGenusComparator一起使用

    必须将这两个集合都转换为TreeSet(GenusComparator),才能使retainAll()正常工作

    我修正了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]