无法在TreeSet中删除重复的对象

时间:2019-04-05 12:28:35

标签: java treeset

我有一个Animal类和Dog类,Dog extends Animal,现在我覆盖了equals类中的hashCodeAnimal方法我使用ArrayList<Dog>方法构建了一个TreeSet并将其放在addAll对象中,但是似乎无法删除重复的Dog对象。参见下面的代码:

动物类:

public class Animal {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    private int age;

    public boolean equals(Object o) {
        Animal animal = (Animal) o;
        System.out.println("equals: " + animal.getName());
        return this.name.equals(animal.getName());
    }

    public int hashCode() {
        System.out.println(name + "'hashCode: " + name.hashCode());
        return this.name.hashCode();
    }
}

狗类:

public class Dog extends Animal {
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

}

这样的测试方法:

private static <T extends Animal> void testSortandRemoveDuplicateElement(List<T> list) {
    System.out.println("Before sort...");
    for(int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i).getName() + ", " + list.get(i).getAge());
    }
    TreeSet<T> set = new TreeSet<T>(new AnimalComparator<T>());
    System.out.println("After sort...");
    set.addAll(list);
    for(T t : set) {
        System.out.println(t.getName() +", " + t.getAge());
    }
}

private static void testDriver1() {
    Dog d1 = new Dog();
    d1.setName("abc");
    d1.setAge(1);

    Dog d2 = new Dog();
    d2.setName("abc");
    d2.setAge(2);

    Dog d3 = new Dog();
    d3.setName("Wxy");
    d3.setAge(0);

    List<Dog> dogList = new ArrayList<Dog>();
    dogList.add(d1);
    dogList.add(d2);
    dogList.add(d3);

    testSortandRemoveDuplicateElement(dogList);
}

出于调试目的,我在Animal类的2个方法中添加了一些打印语句,但似乎没有被调用,我在控制台中看不到这2个方法的任何输出,您能告诉我为什么吗是我必须重写子类Dog,Cat等中的2种方法?我认为这不是一个好方法。

2 个答案:

答案 0 :(得分:2)

如注释中所述,TreeSet使用您提供给它的比较器比较重复项的元素。 因此,如果您的比较器在两个名称相等时返回0,则它应能按预期工作。

示例:尝试使用

TreeSet<T> set = new TreeSet<T>(Comparator.comparing(Animal::getName));

代替

TreeSet<T> set = new TreeSet<T>(new AnimalComparator<T>());

HTH!

答案 1 :(得分:1)

尝试将您的testSortandRemoveDuplicateElement方法更改为以下内容:

private static <T extends Animal> void testSortandRemoveDuplicateElement(List<T> list) {
    System.out.println("Before sort...");
    for(int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i).getName() + ", " + list.get(i).getAge());
    }
    Set<T> set = new HashSet<T>(list);
    Set<T> treeset = new TreeSet<T>(new AnimalComparator<T>());
    treeset.addAll(set);

    System.out.println("After sort...");
    for(T t : set) {
        System.out.println(t.getName() +", " + t.getAge());
    }
}

HashSet将基于equals和hashcode实现消除“重复项”。然后,您可以创建TreeSet来根据比较器对其余元素进行排序。