Java - TreeSet 接受重复项

标签 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();
}

编辑2: 这是 Song 类更新后的 equals 方法、toString 和 compareTo

@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);

虽然还是不行,我觉得好像遗漏了一些明显的东西

编辑3: 解决了,我的测试课实际上犯了一个错误。尴尬。抱歉,并不是要浪费您的时间,希望这对某人有所帮助。

最佳答案

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

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

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

关于Java - TreeSet 接受重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50144820/

相关文章:

java - 需要从HTML页面解析图片src然后显示

r - R 中自定义类的元素列表的排序列表?

java - <identifier> 地址簿比较器出现预期错误

java - TreeSet 违反了 Set 契约?

java - 从 TreeSet 中删除一个对象

java - 为什么我的自定义 JButton 不显示其名称?

java lwjgl 2着色器错误

java - 这个 for 循环如何翻译成英语?

java - 按属性对自定义对象的 ArrayList 进行排序

java - 使用 Hibernate 和 TreeSet 无法使用remove() 和 contains() 方法