Set接口
java.util.Set接口 extends Collection接口
Set接口的特点:
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能使用普通的for循环遍历
java.util.HashSet集合 implements Set接口
HashSet特点:
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能使用普通的for循环遍历
- 是一个无序的集合,存储元素和取出元素的顺序有可能不一致
- 底层是一个哈希表结构(查询的速度非常快)
Set<Integer> set = new HashSet<>(); //使用add方法往集合中添加元素 set.add(1); set.add(3); set.add(2); set.add(1); //使用迭代器遍历Set集合 Iterator<Integer> it = set.iterator(); while(it.hasNext(){ Iterator n = it.next(); System.out.println(n);//1,2,3 无序且不重复 }
HashSet集合存储数据的结构(哈希表)
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址)
在Object类有一个方法,可以获取对象的哈希值
int hashCode() 返回该对象的哈希码值。
HashCode方法的源码:
public native int hashCode(); native:代表该方法调用的是本地操作系的的方法
哈希表
哈希表:hashSet集合存储数据的结构
jdk1.8版本之前:哈希表 = 数组+链表
jdk1.8版本之后:
- 哈希表 = 数组+链表;
- 哈希表 = 数组+红黑树(提高查询的速度)
哈希表的特点:速度快
存储数据到集合中,先计算元素的哈希值
- abc:96354 在数组的存储位置
- 重地——通话:1179395 两元素不同,但是哈希值相同 哈希冲突
数组结构:把元素进行了分组(相同哈希值的元素是一组)
链表/红黑树结构:把相同哈希值的元素连到一起(如何链表的长度超过了8位,那么就会把链转换位红黑树(提高查询的速度))
Set集合存储元素不重复的原理
Set集合存储元素不重复的元素的前提:
前提:存储的元素必须重写hashCode方法和equals方法
//创建HashSet集合对象 HashSet<String> set = new HashSet<>();//哈希表:数组+链表/红黑树 String s1 = new String("abc"); String s2 = new String("abc"); set.add(s1); set.add(s2); set.add("重地"); set.add("通话"); set.add("abc"); System.out.println(set);/[重地,通话,abc]
原因:
Set集合在调用add方法的时候,add方法会调用元素hashCode方法和equals方法,判断元素是否重复
HashSet存储自定义类型元素
Set集合报错元素原因:
存储的元素(String,Integer,…Student,Person…),必须重写hashCode方法和equals方法
LinkedHashSet集合
java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合特点:
底层是一个哈希表(数组+链表/红黑树+链表:多了一条链(记录元素的存储顺序),保存元素有序
HashSet<String> set = new HashSet<>();//[]无序,不允许重复 LinkedHashSet<String> set = new LinkedHashSet<>();[]//有序,不允许重复