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

问题描述 投票:1回答:2

我有一个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个方法?我认为这不是一个好方法。

java treeset
2个回答
2
投票

正如在注释中提到的,TreeSet使用您提供的比较器来比较重复的元素。因此,如果您的Comparator在两个名称相等时返回0,那么它应该按预期工作。

示例:尝试使用

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

代替

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

HTH!


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以根据比较器对其余元素进行排序。

© www.soinside.com 2019 - 2024. All rights reserved.