Set接口:
特点1: 无序,存储的元素与添加顺序无关
特点2: 不可重复(使用元素的equals方法来判定是否重复)
特点3: 能存储null元素,只能存储一次。
Hash算法机制
Set集合在添加或查看元素时,当集合中的元素过多时,就是进行
多次的比较,效率变低。
在设计元素类型时,提供hash算法,用于返回对象的一个哈希值(int)值。
在集合所占的内存中开辟很多小的区域,每个区域用于存储一定范围的哈希值的元素。
当我们想添加元素或检索元素,先获取此元素的哈希值,然后去
对应区域中查找遍历(大大降低了比较次数)
--如果在这个区域,哈希值对应的位置上没有元素,就讲此元素存储到这个位置。
--如果有,然后查看两个对象的equals的返回值
--如果为true, 不能添加
--如果为false, 可以添加,添加至
对应的链表结构中(尽可能的避免发生)
重写HashCode方法:
重写规则:尽可能的让所有的成员变量都参与运算,
尽可能的避免出现hash值碰撞
注意:
重写的必要性:
(1)如果重写了equals(), 有必要重写hashCode方法
(2)如果equals()返回true, hashCode返回值有必要相同
(3)如果equals()返回false,hashCode返回值不一定相同,
如果返回值不同,可以提高检索的效率
反过来说:
(1)hashCode值相同,equals方法可能不同
(2)hashCode值不同,equals方法一定不同
Set接口派生的子类
HashSet:通过实现hash算法的一种数据结构,
无序,不重复
LinkedHashSet:通过实现hash算法的一种数据结构,但是
通过链表来维持顺序。顺序与添加顺序一致。
TreeSet: 使用二叉树的一种数据结构,顺序与自然排序有关系。
支持定制排序
=================
Set集合的遍历
因为Set集合是无序的,无下标可言,因此不能使用经典for
循环。我们可以使用迭代器原理。
(1) 调用集合的iterator()获取迭代器
(2) 使用foreach循环
Set集合的元素:
不能轻易修改参与hash值算法的成员变量。
否则容易引起内存溢出。
原因:成员变量修改后,会出现新的hash值,但是存储位置还在
原hash值的位置上。因此操作时,找不
到具体的存储位置。
子类:
HashSet:
无序,不重复,底层使用hash算法计算存储位置。
增加删除时效率高
LinkedHashSet:是HashSet的子类
底层使用hash算法计算存储位置,同时使用链表来维护
顺序,顺序与添加顺序一致。
在查看检索时,效率比较高
TreeSet:是SortedSet子接口的实现类,使用二叉树的数据结构维护
元素的顺序。
=========================================
Map接口:集合框架中的另一个父接口
Map集合,用于储存一一对应的元素数据,第一个对象可以作为
索引,第二个对象作为值,我们称之为key-value,键值对。
储存数据的特点:
(1)以key-value形式进行存储。
(2)key与value都必须是引用类型
(3)key可以为null。
(4)key与value是单向一对一映射。
(5)key不能重复
存储机制:
Map是基于数组和链表的数据结构进行存储数据。
作为key的对象采用了hash算法计算存储的数组
(散列数组,散列桶)的位置.如果计算出来的位置,
数组中此位置没有元素,就可以添加到
散列桶内,如果有元素,key的equals方法
返回值为false,就会存储在散列桶元素对应的单向链表中。
如果key的equals方法返回true,就进行替换(覆盖)。
PS:使用Map集合,做为key的数据类型应该重写equals和
HashCode方法
常用方法:
V put(K k,V v):
作用:用于存储一对key-value. 返回被替换的value值
如果不是替换就返回null
V get(K k):
作用:通过key对象,获取对应的value对象,如果集合中
没有此key,返回null
Map集合的遍历
Set<K> keySet();
用于获取Map中所有的key对象,返回一个Set集合
Set<Entry<K,V>> entrySet();
将key-value封装成内部类对象,返回Entry对象的Set集合
Collection<V> values();
将map集合中的所有value封装到一个Collection集合中。
装载因子和HashMap的优化
装载因子:DEFAULT_LOAD_FACTOR = 0.75f
默认容量:DEFAULT_INITIAL_CAPACITY
16,就是数组的容量
元素个数: size
当我们创建一个HashMap对象时,底层数组的初始容量为16。当存储的数据的
个数 size/DEFAULT_INITIAL_CAPACITY等于DEFAULT_LOAD_FACTOR时,
数组开始扩容。此时最佳。
如果小于0.75扩容,比较占内存。
如果大于0.75扩容,操作的元素比较多。
============================
Map接口的子类:
HashMap与HashTable的区别
(1)HashTable是一个古老的类。不建议使用
(2)HashTable是一个线程安全的类,HashMap线程不安全
(3)HashTable的key不能是null,HashMap可以是null
LinkedHashMap:是HashMap子类,使用链表来维护key-value的
顺序,在迭代时顺序与添加顺序一致。
TreeMap:
是SortedMap子接口的实现类,使用了二叉树的数据结构维护
填入集合的顺序。
(1)自然排序:
往TreeMap里添加的key对象,可以实现Comparable接口。重写
compareTo方法
(2)定制排序:做为key对象的数据类型,可以不实现Comparable接口。
需要创建一个比较器Comparator对象。实现compare方法
Properties:
是HashTable的子类型,用于封装属性文件的key-value信息
因为在文件里写的都是字符串,因此Properties的key与value
都是字符串类型