Java - 接受重复的TreeSet

时间:2018-05-02 23:14:44

标签: java comparator treeset

我遇到了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);
    }
}

编辑:这是我实现hashCode和equals的方式:

@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 for class 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

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

仍然没有工作,我觉得好像我错过了一些明显的东西

EDIT3: 解决了,我的Test课程实际上犯了一个错误。尴尬。对不起,不是浪费你的时间,我希望这会对某人有所帮助。

2 个答案:

答案 0 :(得分:4)

TreeSet是用Java中的平衡二叉树实现的(实际上是RedBlack树)。所以它不使用equals方法。它使用Comparator

现在您的实施问题与您的comparator有关。 您的比较器基于toString方法。默认情况下,java返回对象类的名称及其哈希码。因此,默认情况下,toString的输出对于两个对象是相同的,当且仅当它们指向相同的内存引用时。您需要确保在比较器的基础上覆盖了类中的toString方法。

要解决此问题,您需要定义一个反映程序比较逻辑的比较器。

答案 1 :(得分:0)

TreeSet在后​​台使用TreeMap代表虚拟值。 因此,与其使用棘手的比较器来允许重复,不如使用具有重复计数的值切换到TreeMap会更容易,而且内存效率更高。

以下是示例:How do I use a TreeSet in Java that allows Duplicates?

相关问题