我的代码上有两个集合,在它们上面我添加了相同的元素集合。问题是,TreeSet不会添加所有元素。我有点困惑。
我现在有一段时间的问题了,我正在努力找出为什么我的TreeSet不会添加我传递给addAll的Collection中的所有元素。
这是一个带有比较器的TreeSet构建,用于具有等于方法的项目:
public final boolean equals(Object o) {
return this==o;
}
@Override
public int hashCode() {
int hash = 3;
hash = 67 * hash + Objects.hashCode(this.grauDeAdaptacao);
hash = 67 * hash + Objects.hashCode(this.idade);
return hash;
}
为了测试我做了以下事情:
HashSet<Item> test1 = new HashSet<>(items);
TreeSet<Item> test2 = new TreeSet<>(getComparator());
test2.addAll(items);
if (test1.size() < 50 || test2.size()<50 ) {
throw new IllegalStateException();
}
比较器使用:
private int compare(S ser1, S ser2) {
return ser1.getGrau().compareTo(ser2.getGrau());
}
但令人尴尬的是,散列接缝很好,而TreeSet没有全部50个元素。
我需要两个元素在相同的实例中相同,在所有子类中,这就是我制作最终方法的原因。
答案 0 :(得分:2)
HashSet
使用equals
来测试两个对象是否相等。
HashSet
保证a
b
中任何两个不同的对象Set
和a.equals(b) == true
绝不会出现。
TreeSet
使用compareTo
来测试两个对象是否相等。
TreeSet
保证a
b
中任何两个不同的对象Set
和a.compareTo(b) == 0
绝不会出现。
假设a.compareTo(b) == 0
iff a.equals(b)
,则此行为相同。在这种情况下,可以说compareTo
方法“与equals
”一致,如documentation for Comparable
同样的文件还指出:
强烈建议(尽管不要求)自然 排序与平等一致。这是因为排序集 没有显式比较器的(和排序的地图)表现得“奇怪” 它们与自然顺序的元素(或键)一起使用 与equals不一致。特别是,这样的排序集(或排序的 map)违反了定义的集合(或映射)的一般合同 就平等方法而言。
这是“行为”奇怪“'的一个例子。
您有一些a.equals(b) == false
但 a.compareTo(b) == 0
的对象。
应进一步注意,hashCode
的实施必需,如果a.equals(b) == true
则a.hashCode() == b.hashCode()
。您的实施中不是。鉴于您实施hashCode()
。
equals
的实施无效
反身属性不是必需的。也就是a.hashCode() == b.hashCode()
和a.equals(b) == false
。
总而言之。
hashCode
和equals
错了。它们需要保持一致,如equals
和hashCode
。comapreTo
错误,应与documentation for Comparable
中描述的“{1}}”一致。答案 1 :(得分:0)
当然,在你的帮助下解决了。 因为我需要一个有效插入和搜索的数据结构,而它总是排序 - 来自Java SE API。 TreeSet太简单了,不能使用它。所以我调整了比较器和项目以使用ID。就像树很高兴,它用我想要的属性命令我的元素,如果它们是相同的,ID将决定顺序......它与equals兼容,并且每个人都很高兴。