Java TreeSet не удаляет дубликаты пользовательского объекта с пользовательским compareTo.

Вопрос или проблема

Я пытаюсь удалить дублирующиеся объекты, дублирующиеся, когда _id одинаковый или email одинаковый.

Мой пользовательский CompareTo:

 @Override
    public int compareTo(Lead other) {
         
        // Сравниваем сначала по ID
        int idComparison = this._id.compareTo(other._id);
        if (idComparison != 0) {
            return idComparison;
        }
        
        int emailComparison = this.email.compareTo(other.email);
        if (emailComparison != 0) {
                return emailComparison;
       }

        
        // Если ID одинаковы, сравниваем по дате (последние сначала)
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            Date date1 = dateFormat.parse(this.entryDate);
            Date date2 = dateFormat.parse(other.entryDate);

            return date1.compareTo(date2);
        } catch (ParseException e) {

            return 0; // Обработайте ошибки парсинга соответствующим образом
        }

Мои объявленные и инициализированные данные

 // конвертируем данные JSON в объект Java
        LeadsData leads = gson.fromJson(reader, LeadsData.class);

        // Удаляем дубликаты, используя TreeSet
        TreeSet<Lead> уникальныеЗаписи = new TreeSet<>(leads.leads);

Я не уверен, где я ошибся. Я проверял документацию TreeSet, она кажется довольно простой.

Ответ или решение

Для решения проблемы с удалением дублирующихся объектов в Java с использованием TreeSet, важно понимать, как работает метод compareTo и как именно TreeSet определяет уникальность объектов. Давайте рассмотрим ваш случай более подробно.

Проблема с удалением дубликатов

Вы столкнулись с проблемой, когда TreeSet не удаляет дубликаты пользовательских объектов Lead, несмотря на наличие правильно реализованного compareTo метода. Чтобы это исправить, необходимо убедиться, что ваши объекты правильно сравниваются, а также что они реализуют методы equals и hashCode.

Реализация compareTo

Ваш метод compareTo выглядит следующим образом:

@Override
public int compareTo(Lead other) {
    // Сравниваем по ID в первую очередь
    int idComparison = this._id.compareTo(other._id);
    if (idComparison != 0) {
        return idComparison;
    }

    int emailComparison = this.email.compareTo(other.email);
    if (emailComparison != 0) {
        return emailComparison;
    }

    // Если IDs одинаковые, сравниваем по дате (последняя дата первой)
    try {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        Date date1 = dateFormat.parse(this.entryDate);
        Date date2 = dateFormat.parse(other.entryDate);

        return date1.compareTo(date2);
    } catch (ParseException e) {
        return 0; // Обработка ошибок парсинга
    }
}

Хотя логика сравнения выглядит корректной, TreeSet использует метод compareTo для определения порядка объектов, а не для проверки их равенства. Если два объекта равны, как по естественному порядку, так и по equals, это значит, что TreeSet будет хранить только один из них. Из-за этого даже если compareTo правильно сравнивает объекты, вы можете не видеть ожидаемого поведения, если не реализованы методы equals и hashCode.

Реализация equals и hashCode

Для правильного функционирования TreeSet необходимо также переопределить методы equals и hashCode. Вот пример, как это можно сделать:

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (!(obj instanceof Lead)) return false;

    Lead other = (Lead) obj;
    return this._id.equals(other._id) || this.email.equals(other.email);
}

@Override
public int hashCode() {
    return Objects.hash(_id, email);
}

В данном случае метод equals будет считать два объекта одинаковыми, если у них совпадают либо _id, либо email. Это точно соответствует вашей бизнес-логике, где дубликаты определяются по этим критериям.

Подводя итоги

  1. Убедитесь, что ваш метод compareTo реализован правильно и определяет естественный порядок объектов.
  2. Переопределите методы equals и hashCode, чтобы обеспечить корректное поведение TreeSet.
  3. Проверьте, что данные, которые вы передаете в TreeSet, корректно инициализированы и не содержат неожиданных значений.

Следуя этим рекомендациям, вы сможете успешно удалить дублирующиеся объекты из коллекции TreeSet и обеспечить сохранение уникальности ваших записей.

Оцените материал
Добавить комментарий

Капча загружается...