Java - TreeSet принимает дубликаты - PullRequest
0 голосов
/ 03 мая 2018

У меня проблемы с TreeSet: почему этот принимает дубликаты? Я думал, TreeSets обнаружил их через компаратор и автоматически удалил их. Пожалуйста, помогите мне, я новичок в Java и StackOverflow.

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class SortedSongs
{   
    private Set songs;
    public SortedSongs()
    {
         Comparator<Song> comp = (Song c1, Song c2)-> c1.toString().compareTo(c2.toString());
         songs = new TreeSet<>(comp);
    }
}

edit: вот как я реализовал hashCode и равен:

@Override
public int hashCode()
{
    return Objects.hash(name, author);
}

@Override
public boolean equals(Object o)
{
    return o == null ? false : o.getClass() != getClass() ? false
        : o.hashCode() == hashCode();
}

edit2: Это обновленный метод equals, toString и compareTo для класса Song

@Override
public boolean equals(Object o)
{
    if (this==o) return true;
    if (getClass()!=o.getClass()) return false;
    return name.equals(((Song) o).name) && author.equals(((Song) o).author);
}
@Override
public String toString() {return name + " - " + author;}

public int compareTo(Song other)
{
    if (name.equals(other.name))
        return author.equals(other.author) ? 0 : author.compareTo(other.author);
    return name.compareTo(other.name);
}

Так что теперь компаратор в SortedSongs

Comparator<Song> comp = (Song c1, Song c2)-> c1.compareTo(c2);

Хотя все еще не работает, я чувствую, что упускаю что-то очевидное

Edit3: Решено, я действительно допустил ошибку с моим тестовым классом. Неловко. Извините, я не хотел тратить ваше время, надеюсь, это кому-нибудь пригодится.

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

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

Вот пример: Как использовать TreeSet в Java, который позволяет дублировать? .

0 голосов
/ 03 мая 2018

TreeSet реализовано с помощью сбалансированного бинарного дерева в Java (на самом деле это дерево RedBlack). Так что он не использует метод equals. Он использует Comparator.

Теперь проблема с вашей реализацией связана с вашей comparator. Ваш компаратор основан на методе toString. По умолчанию java возвращает имя класса объекта плюс его хеш-код. Таким образом, по умолчанию вывод toString будет одинаковым для двух объектов, если и только если они указывают на одну и ту же ссылку на память. Вам необходимо убедиться, что вы переопределили метод toString в своем классе, поскольку ваш компаратор основан на этом.

Чтобы решить эту проблему, вам нужно определить компаратор, отражающий логику сравнения вашей программы.

...