Set集合
Set是Collection集合的子接口,Set集合中存储元素是无序.排除重复.
Set集合主要使用的是Hash算法HashSet集合–>子类LinkedHashSet集合 TreeSet集合
什么是Hash算法?Hash一般你会被翻译为"散列",也有直译"哈希"的,它是为了快速存取的角度而设计,这里的计算原则即"空间置换"–>空间换时间 Hash的组成 -->是一种线性表 --> “数组+链表”
散列表,是根据键值对可以通过映射的关系记录存储的位置,以加快查找,这个映射函数叫做"散列函数"存放记录的位置就叫做"散列表"
假如:存储70个元素,但是存70个元素申请了100个空间, 70 / 100 = 0.7 这个数字就是负载(加载)因子
因为存储数据的时候是存储到散列表中,会存在一个问题即连个元素通过散列函数计算的到的地址是相同,那么这两个元素可以称为"同义词",散列函数计算的记过户存储到一个具体的单元,称为"桶" ,桶的范围是从0开始到最大值-1
ps:就是数组下标
Set集合中主要实现类是HashSet使用就是Hash算法进行数据存储
元素是存储到hash表中
hash表—>数组+链表的形式实现的, 数组作为位置存在,链表作为具体值的存储散列函数 -> hash(key)%len -->计算出存的位置
扩容问题
Java中的散列表单元大小都是2的幂,初始大小为16(即2的4是幂)默认系统提供的加载(负载)因子0.75,当存的数据达到加载因子的时候(即16*0.75 = 12),此时HashSet将会重新计算散列表,将里面原有的散列结构全部抛弃,重新开辟一个散列空间大小为32(即2的5次幂),此时会重新计算所有数据并将数据重新存储,当前hash表扩容性能较低
排重机制
假如:存一个数据(散列码[hashcode]76268),而此时的HashSet有128个散列单元那么这个数据可以存在数组的108位置(76268%128) =108,但是有一种可能,如果在地108号为的链表中发现有一个和当前数值完全一样的值即equals方法比较结果为true,此时这个新数据就不会再添加这个链表中了
ps:存值的原则必须是equals和hashcode
因为Hash表是数组+链表实现,所以插入和查询效率是非常高的
常用方法:
/**
* @author calorie
*
*/
public class text {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
HashSet hs = new HashSet();
// 1.添加元素
hashSet.add("1");
hashSet.add(1); // 未引入泛型所以可以加入任意类型的数据
hashSet.add(1);
hashSet.add("2");
System.out.println(hashSet); // 打印结果为[1, 1] 内部自动排重
// 2.将集合添加到新的集合中
boolean a = (new HashSet().addAll(hashSet));
hs.addAll(hashSet);
System.out.println(a);
System.out.println(hs);
// 3.清空集合
hs.clear();
System.out.println(hs);
// 4.判断是否存在指定元素
boolean ifcontains = hashSet.contains(1);
System.out.println(ifcontains);
// 5.判断参数集合中提供数据是否在当前集合中
// HashSet.containsAll(hs)
// 6.判断集合是否为空
boolean em = hashSet.isEmpty();
System.out.println(em);
// 7.Set集合遍历
Iterator it = hashSet.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
//8.删除指定元素
boolean remove = hashSet.remove(1);
System.out.println(remove);
//9.removeAll(集合对象) 删除指定集合对象中所提供元素
//10.retainsAll 保留集合中提供元素,删除剩余元素
//11.set.size()获取集合元素的个数
//12.将set集合转变为数组
Object[] array = hashSet.toArray();
}
}
ps:HashSet有一个子类LinkedHashSet,使用了链表实现,多了顺序问题,没有特定API所以HashSet如何操作LinkedHashSet就如何操作
TreeSet:
TreeSet集合是一个自带排序的集合,也继承Set集合这边的排重功能
默认是升序排序 从小到大
TreeSet在JDK1.7之前是二叉树,JDK1.8之后使用是红黑二叉树(平衡二叉树)
TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。这取决于使用的构造方法。