基于长期对HashMap与HashSet的混淆,所以特意搜集资料加上自己的整理写了这篇博客。
1.HashMap与HashSet的区别:
1.)HashSet不允许有重复元素出现且实现了Set接口,仅存储对象(HashSet存储自定义类型(即:泛型为自定义类---文末解释)),获取对象的速度相对较快,当我们使用HashSet存储自定义类时,需要在自定义类中重写equals和hashCode方法,主要原因是集合内不允许有重复的数据元素,在集合校验元素的有效性时(数据元素不可重复),需要调用equals和hashCode验证。 Hash算法就是把任意长度的输入(又叫做预映射),通过散列算法,变换成固定长度的输出,该输出就是散列值。 这种转换是一种压缩映射,对于不同类型的信息,其散列值公式亦不完全相同。
HashSet在判断数据元素是否重复时: 1. 检查hashCode值是否与集合中已有相同。 2. 如果hashCode相同再调用equals方法进一步检查。(equals返回真表示重复);
如首先创建数据元素类Student,用于存储到HashSet中,并重写equals方法和hashCode方法。
常用方法总结:
序号 | 方法 | 描述 |
1 | size() | 获取Set尺寸(即Set包含数据元素的总数) |
2 | add(Object obj) | 向Set中添加数据元素obj |
3 | remove(Object obj) | 从Set中移除数据元素obj |
4 | contains(Object obj) | 判断当前Set中是否包含数据元素obj,如果包含返回true,否则返回false |
5 | iterator() | 将Set装入迭代器 |
2.)HashMap实现了Map接口,Map接口对键值对进行映射(仅存储键值对),HashMap是非线程安全的(若要想实现线程安全,则需要调用collections类的静态方法synchronizeMap()实现。),
Map接口有两个基本的实现:TreeMap和Ha
shMap。其中TreeMap保存了对象的排列次序,而HashMap不能,Map中不允许出现重复的键(Key),并且每个键(key)只能对应一个值(value),HashMap通过hash算法排布存储Map中的键(key),HashMap也是最常用的图状数据结构,其存储的数据元素是成对出现的。 HashMap中的数据元素不是按照我们添加的顺序排布的,并且其内存模式也不是连续的,但是其key值的排布是根据Hash算法获得的,所以在数据元素的检索方面速度还是较快的。 HashMap不能直接装入迭代器,必须将HashMap的所有键key装入迭代器,再进行遍历,或者是使用Entry类,将所有数据元素转化为Entry的集合进行处理。
常用方法总结:
序号 | 方法 | 描述 |
1 | size() | 获取Map尺寸(即Map包含数据元素key-value对的总数)。 |
2 | put(Object key, Object value) | 向Map中添加数据元素,key为键,value为值,键和值是一一对应关系。 |
3 | remove(Object key) | 根据键key从Map中移除数据元素。并返回被删除元素的值value。 |
4 | get(Object key) | 通过map的key值获取对应的value值 |
序号 | 方法 | 描述 |
5 | containsKey (Object obj) | 判断当前Map中是否包含键obj,如果包含返回true,否则返回false。 |
6 | keySet() | 返回由Map中的所有键组成的集合。 |
7 | entrySet() | 将Map中的键-值对存入集合,该集合的数据元素是Entry类的对象,Entry类具有两个成员变量key和value来描述原Map中的键和值。 |
8 | values() | 获取Map中的全部值组成一个Collection对象。 |
另外:TreeMap是一种有序的映射关系,即每对键key-值value在TreeMap中是有序排列的,并且这个序列遵循自然序列,当我们向TreeMap插入新的数据元素时,TreeMap可能会重新排序,所以TreeMap中的任何元素在整个映射组中是不固定的。 当我们的TreeMap键(key)是自定义类时,需要在自定义类中重写compareTo方法,以提供比对形式,否在TreeMap不能对用户自定义的类型的键(key)进行正确的树状排序,也就不能对整个键值对起到有效的排序效果。
TreeMap是Map的实现类,除实现Map接口的所有方法外,增加了一些与序列有关的如下方法:
序号 | 方法 | 描述 |
1 | firstKey() | 获取TreeMap第一个Key值 |
2 | lastKey() | 获取TreeMap最后一个key值 |
3 | headMap(end) | 获取TreeMap中从第一个开始到end-1位置的所有元素,组成一个排序映射(SortedMap) |
4 | tailMap(start) | 获取TreeMap中从start开始到最后一个元素之间的所有元素,组成一个排序映射(SortedMap) |
常用集合类主要分为如下Collection和Map两大分支。橙色表示接口,蓝色表示实现类。
泛型的本质:泛型也是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。 Java语言引入泛型的好处是安全简单。 对于数据结构来说,泛型用于指定当前数据结构存储的元素类型,例如:ArrayList<String>表示当前的数组线性表只能存储String类型的数据。 也可以在List中存储自定义,例如:LinkedList<Student>表示当前的双向链表中只能存储Student的对象。