Set集合特征
特征:无序,不可重复。
- 无序:添加顺序和存储顺序不一致
- 不可重复: 在一个Set集合中不能出现相同元素
HashSet 的实现原理?
HashSet 是基于 HashMap 实现的,HashSet的值存放于HashMap的key上,HashMap的value统一为PRESENT,因此 HashSet 的实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成,HashSet 不允许重复的值。
HashSet如何检查重复?
- HashSet中add()方法调用的是底层HashMap中的put()方法,而如果是在HashMap中调用put(),首先会判断key是否存在,如果key存在则修改value值,如果key不存在这插入这个key-value。
- 而在set中,因为value值没有用,也就不存在修改value值的说法,因此往HashSet中添加元素,首先判断元素(也就是key)是否存在,如果不存在这插入,如果存在着不插入,这样HashSet中就不存在重复值。
HashSet是如何保证数据不可重复的?
所以判断key是否存在就要重写元素的类的equals()和hashCode()方法。
- 当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算次对象的哈希值,此哈希值决定了此对象在Set中存放的位置;
- 若此位置没有被存储对象则直接存储,若已有对象则通过对象所在类的equals()比较两个对象是否相同,相同则不能被添加。
hashCode()与equals()的区别与联系
- 如果两个对象相等,则hashcode一定也是相同的
- 两个对象相等,对两个equals()方法返回true
- 两个对象有相同的hashcode值,它们也不一定是相等的
- 所以equals()方法被覆盖过,则hashCode()方法也必须被覆盖
- hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。
==与equals的区别
- == 是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同
- ==是指对内存地址进行比较 , equals()是对字符串的内容进行比较
- ==指引用是否相同, equals()指的是值是否相同
HashTable与HashMap的区别
- Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的。
- HashMap允许存在一个为null的key,多个为null的value 。
- hashtable的key和value都不允许为null。
HashSet与HashMap的区别
HashMap | HashSet |
---|---|
实现了Map接口 | 实现Set接口 |
存储键值对 | 仅存储对象 |
调用put()向map中添加元素 | 调用add()方法向Set中添加元素 |
HashMap使用键(Key)计算Hashcode | HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false |
HashMap相对于HashSet较快,因为它是使用唯一的键获取对象 | HashSet较HashMap来说比较慢 |
整个Set接口中有以下三个可能见到的子类
HashSet:无序存放
- 打开源代码之后发现整个HashSet类里面存在有一个HashMap,但是很明显,没使用这个Map的Value,只使用了Key(HashMap的主要特点是key不能重复);
- 在HashSet类执行add()方法的时候发现是利用了Map接口中的put()实现的;
- 在整个存储过程之中存在有一个hashCode()的使用;
- 在内部的Node类处理时依然使用了equals()判断key与value内容。
TreeSet:发现使用的是Map集合(SortedMap接口子类)
- 里面存放的是TreeMap,TreeMap的特点在于所有的key都是可以排序的,排序的依据是Comparable(往往会忽略掉Comparator);
- 在TreeMap之中对于大小的关系判断强制使用了Comparable接口中的compareTo()完成。
- TreeSet中保存的数据都必须是Comparable接口的子类。
LinkedHashSet
- 如果这个时候需要进行连续的保存(FIFO),就可以使用另外一个子类。它之所以可以进行顺序保存,是因为在进行存储的时候采用的是链表形式完成的。