我遇到了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课程实际上犯了一个错误。尴尬。对不起,不是浪费你的时间,我希望这会对某人有所帮助。
答案 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?。