简单来说,就是2楼所说的数据结构不同,一个是哈希表,一个是二叉树。如果打破砂锅问到底,那就要了解哈希表和哈希值到底是什么东东。
访问数组元素之所以快,是因为可以用下标访问。只要知道数组的起始地址,比如说一个int数组的起始地址是a,那么第k个元素的地址就是a+k*4,一步就能找到任意位置的元素。哈希值也是类似数组下标的思路:给每个对象编个号(还记得hashCode()方法返回值是int么),只要告知编号,对应的对象就找到了。这种哈希值和对象的对应关系就组成了哈希表。
理想情况下,我们希望每个对象都分配一个唯一的编号,这样查找起来最快。但是任何事情都是有代价的。按这种方法,如果有1万个不同对象,哈希表的长度就是1万行,存储空间开销巨大。这时候我们就需要做一点权衡,允许多个不同对象有相同的哈希值(hashCode()对不同对象可以返回相同的值)。
比如,1万个对象,我开辟100个哈希值,你可以想象成100只桶,那么平均每只桶(哈希值)内放100个对象(让对象尽可能均匀分布于桶中是评价hashCode()方法优劣的主要指标)。这样当我要查找某个对象时,就分为两个步骤:1.找桶2.桶内找对象。找桶的步骤对应的就是hashCode()方法。1万个对象,通过找桶,我就排除了9900个对象,只要在hashCode()返回值所在的桶中找就可以了。在桶中找,就需要第二个方法来确定我要找的到底是哪个对象,于是equals()方法闪亮登场了。这就是HashSet需要两个方法的原因
|