如果希望元素可以重复,又有索引,索引查询要快?
如果希望元素可以重复,又有索引,增删首尾操作快?
如果希望增删改查都快,但是元素不重复、无序、无索引。
如果希望增删改查都快,但是元素不重复、有序、无索引。
如果要对对象进行排序。
数组的特点
集合的特点
1、数组和集合的元素存储的个数问题。
2、数组和集合存储元素的类型问题。
3、数组和集合适合的场景
集合体系结构
Collection集合体系
Collection集合的特点
1、集合的代表是?
2、Collection集合分了哪2大常用的集合体系?
3、如何约定集合存储数据的类型,需要注意什么?
为啥要先学Collection的常用方法?
Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。
Collection的常见方法如下:
方法名 | 说明 |
---|---|
public boolean add(E e) | 把给定的对象添加到当前集合中 |
public void clear() | 清空集合中所有的元素 |
public boolean remove(E e) | 把给定的对象在当前集合中删除 |
public boolean contains(Object obj) | 判断当前集合中是否包含给定的对象 |
public boolean isEmpty() | 判断当前集合是否为空 |
public int size() | 返回集合中元素的个数。 |
public Object[] toArray() | 把集合中的元素,存储到数组中 |
迭代器是用来遍历集合的专用方式(数组没有迭代器),在Java中迭代器的代表是Iterator。
Collection集合获取迭代器的方法
方法名称 | 说明 |
---|---|
Iterator iterator() | 返回集合中的迭代器对象,该迭代器对象默认指向当前集合的第一个元素 |
Iterator迭代器中的常用方法
方法名称 | 说明 |
---|---|
boolean hasNext() | 询问当前位置是否有元素存在,存在返回true,不存在返回false |
E next() | 获取当前位置的元素, 并同时将迭代器对象指向下一个元素处。 |
Iterator<String> it = lists.iterator();
while(it.hasNext()){
String ele = it.next();
System.out.println(ele);
}
1、迭代器的默认位置在哪里。
Iterator<E> iterator():得到迭代器对象,默认指向当前集合的索引0
2、迭代器如果取元素越界会出现什么问题。
会出现NoSuchElementException异常。
1、增强for可以遍历哪些容器?
2、增强for的关键是记住它的遍历格式
for(元素数据类型 变量名 : 数组或者Collection集合) { //在此处使用变量即可,该变量就是元素 }
Collection<String> c = new ArrayList<>(); ...
for(String s : c) {
System.out.println(s);
}
增强for可以用来遍历集合或者数组。
增强for遍历集合,本质就是迭代器遍历集合的简化写法。
Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。
需要使用Collection的如下方法来完成
方法名称 | 说明 |
---|---|
default void forEach(Consumer super T> action) | 结合lambda遍历集合 |
Collection<String> lists = new ArrayList<>(); ...
lists.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
转为
lists.forEach(s -> {
System.out.println(s);
});
// lists.forEach(s -> System.out.println(s));
问题引出
怎么保证遍历集合同时删除数据时不出bug?
有序,可重复,有索引。
collection集合体系
List集合特有方法
方法名称 | 说明 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
List集合的遍历方式有几种?
利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组
添加第一个元素时,底层会创建一个新的长度为10的数组
List
存满时,会扩容1.5倍
如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准
List集合的遍历方式有几种?
基于双链表实现的
查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。
什么是链表? 有啥特点?
特点:
LinkedList集合的特有功能
方法名称 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
可以用来设计队列
可以用来设计栈
Collection集合体系
Set系列集合特点: 无序; 不可重复
HashSet:无序、 不重复、无索引.
LinkedHashSet: 有序、不重复、无索引。
TreeSet: 排序、不重复、无索引。
注意:
注意:在正式了解HashSet集合的底层原理前,我们需要先搞清楚一个前置知识:哈希值!
public int hashCode():返回对象的哈希码值。
对象哈希值的特点
HashSet集合判定两个对象的标准就是两个对象的hash值是否一致, 因此我们经常重写hashcode实现集合中对象去重
哈希表的组成
在了解哈希表之前需要先理解哈希值的概念
哈希值
Object类的API
对象的哈希值特点
哈希表的详细流程
JDK8开始,当链表长度超过8,且数组长度>=64时,自动将链表转成红黑树
了解数据结构
(树)
二叉树存在的问题:
平衡二叉树
红黑树,就是可以自平衡的二叉树
/*
HashSet集合的底层原理
JDK8之前: 数组+链表
JDK8开始: 数组+链表+红黑树
树结构
二叉树: 基本模型
每一个根节点最多只能有两个子节点,子节点数量称为度,树的总层数为树高
左子节点
右子节点
左子树
右子树
二叉查找/二又搜索树: BST (Binary Search Tree)
小的存左边,大的存右边,相同则不存
如果数据已经排好序,那么存入二又树查找树,会形成类似链表结构,查询效率还是低
如果左、右子树的树高差比较大,那么导致左右子树不平衡,影响查询效率
平衡二叉树: AVL (Balanced Binary Tree)
有规律且相对平衡的二叉树
当插入一个元素,导致左右子树的树高差大于1。那么就会触发旋转
旋转分为左旋和右旋,用来保证左右子树的相对平衡
红黑: RBT (Red-Black Tree)
特殊的/自平衡的二又查找树,是计算机科学中用到的一种数据结构
1972年出现时被称为平衡二叉树,后来1978年被修改为如今的红黑树
红黑树不是高度平衡的,有自己保证平衡的规则(红黑规则),性能较好,红黑规则如下:
每一个节点都是红色或者黑色的
根节点必须是黑色的
两个红色节点不能相连
如果一个节点没有子节点,则该节点相应的指针属性为Nil (称为叶子结点),叶子结点是黑色的
对于每一个节点,到其所有后代叶节点的简单路径上,包含的黑色 节点数量相同
*/
手撕平衡二叉树
手撕红黑树
JDK8开始,当链表长度超过8,且数组长度>=64时,自动将链表转成红黑树
HashSet集合的底层原理是什么样的?
结构: 数组 + 链表 8-
数组 + 链表 + 红黑树 8+
数组初始16,加载因子0.75, 新数组是原来老数组的2倍
对元素进行HashCode % 16[0~15]
如果索引对应的值是null, 先equal比较, 如果一样不存储,
如果不一样, 8- 存储新的, 老的挂载新的下面 8+ 新的挂载到老的下面
扩容: 加载因子计算什么时候开始扩容 16 * 0.75= 12
创建新的数组, 长度是原来的两倍, 重新计算索引放入新的数组中
基于哈希表实现的。
JDK8之前的,哈希表:底层使用数组+链表组成
JDK8开始后,哈希表:底层采用数组+链表+红黑树组成。
HashSet集合利用哈希表操作数据的详细流程是咋回事?
注意:
方式一:自然排序
方式二:比较器排序
public TreeSet(Comparator<? super E> comparator)
TreeSet集合的特点是怎么样的?
TreeSet集合对自定义类型的对象排序,有几种方式指定比较规则?
Collection集合特点
1、如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据?
2、如果希望记住元素的添加顺序,且增删首尾数据的情况较多?
3、如果不在意元素顺序,也没有重复元素需要存储,只希望增删改查都快?
4、如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快?
5、如果要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快?