如何使用自定义比较器或equals方法查找“设置差异"? [英] How to find Set difference with custom Comparator or equals method?

查看:74
本文介绍了如何使用自定义比较器或equals方法查找“设置差异"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用与类 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.

通常,我会将 List 转换为 Set 并使用

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

  1. 包装类并覆盖equals方法
  2. 使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆