Повторяющийся объект не может быть удален в TreeSet - PullRequest
1 голос
/ 05 апреля 2019

У меня есть класс Animal и класс Dog, Dog extends Animal, и я переопределяю методы equals и hashCode в классе Animal, теперь я построил 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);
}

для целей отладки я добавил несколько операторов print в эти 2 метода в классе Animal, но, похоже, они не были вызваны, я не вижу никаких выводов этих 2 методов в консоли, можете ли вы сказать мне, почему, это так? значит я должен переопределить что 2 метода в подклассе Dog, Cat и так далее? Я не думаю, что это хороший способ.

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

Как упоминалось в комментариях, TreeSet использует предоставленный им компаратор для сравнения элементов на наличие дубликатов.Поэтому, если ваш Comparator возвращает 0, когда два имени равны, он должен работать так, как вы ожидаете.

Пример: попробуйте использовать

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

вместо

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

HTH!

1 голос
/ 05 апреля 2019

Попробуйте изменить метод 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 для сортировки оставшихся элементов в соответствии с вашим компаратором.

...