为什么自定义比较器不能与hashSet一起使用来检查重复对象

问题描述 投票:0回答:2

我想使用自定义比较器从

HashSet
.

中过滤重复对象

Mobile
类中,我定义了一个非静态嵌套
Comparator
类用于比较。该比较器使用的标准是
id
对象的
Mobile
字段。

Set<Mobile> treeSet = new TreeSet<>(new Mobile().new Comparator()); // works


Set<Mobile> hashSet = new HashSet<>(new Mobile().new Comparator()); // does not work

尽管它对

TreeSet
完美运行,但当我使用
HashSet
,

尝试此操作时,Eclipse 显示语法错误

如果我想使用

equals
,我似乎需要覆盖
hashcode
类中的
Mobile
HashSet
方法。但是,我更愿意使用比较器。

为什么会这样?

java eclipse hashset
2个回答
2
投票

Hashset 被设计为不接受重复!。因此,如果您的集合不包含给定元素,它将把它添加到集合中。但是,如果在您的集合中出现这样的元素,则不会添加第二个(相同)元素并将其丢弃。

哈希集:

class 为基本操作(添加, 删除、包含和大小)。它不保证
的顺序 元素将随着时间的推移保持不变 迭代性能取决于 关于 HashSet 的初始容量和负载因子。这是
接受默认负载系数非常安全,但您可能想要指定
初始容量大约是您预期大小的两倍
集成长。

树集:

保证基本操作(添加、删除和删除)的 log(n) 时间成本 contains) 保证集合的元素将被排序(升序, 自然的,或者你通过它的构造函数指定的)不 为迭代性能提供任何调整参数提供一些 处理有序集的便捷方法,如 first()、last()、 headSet() 和 tailSet() 等

重点:

都保证元素的无重复集合一般是 更快地将元素添加到 HashSet,然后转换集合 到 TreeSet 以进行无重复的排序遍历。都不是 实施是同步的。也就是说,如果多个线程访问一个 并发设置,并且至少有一个线程修改了集合,它 必须在外部同步。 LinkedHashSet 在某种意义上是 介于 HashSet 和 TreeSet 之间。实现为哈希表 有一个链表贯穿其中,但是它提供 与排序遍历不同的插入顺序迭代 由 TreeSet 保证。


0
投票

HashSet
由哈希表支持,哈希表是一种无序的数据结构。这就是为什么它不需要比较器的原因。另一方面,
TreeSet
由二叉搜索树(有序结构)支持,因此它需要一个比较器。

哈希表的正确性依赖于

equals
方法,而其性能依赖于精心选择的
hashCode
。您可以在
HashSet
的 Javadoc 和
Object.hashCode()
方法本身中阅读更多相关信息。

© www.soinside.com 2019 - 2024. All rights reserved.