java - 如何使用自定义 Comparator 或 equals 方法查找 Set 差异?

标签 java set comparator

我想找出两个Set<T>之间的区别使用与 T 类使用的不同的等式度量,例如自定义 Comparator<T>

例如,我有一个类(class) 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>我想找到两个列表之间共享属的交集。

通常,我会转换 ListSet并使用 retainAll 找到交点。但在这里,这将给出共享物种的交集,而不是共享属的交集。

我想使用类似 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. 使用 TreeSet 使用自定义比较器

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

最佳答案

最简单的方法是简单地使用 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]

关于java - 如何使用自定义 Comparator 或 equals 方法查找 Set 差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37956655/

相关文章:

java - Tomcat 8 - 虚拟主机不重新编译 JSP 或识别更新的类

java - 在运行时编译 java 文件可以在 eclipse 上工作,但不能从导出的可运行 jar 文件中工作

java - 在 android 中填充列表时找不到资源

java - 在 Java 中使用位串设置问题

list - 在有限集上定义一个类似于 "arg max"的函数,并证明它的一些属性,并避免通过列表绕道而行

java - 使用自定义比较器会导致排序不一致

java - addWindowListener 使用困难

C++ 设置迭代器删除

java - 比较字符串时使用 Comparable 接口(interface)

Java 异常 : Comparison method violates its general contract