文章目录
集合
概述
用来存数据的容器
长度可变>取代数组的原因
只能存对象
集合只能临时存储数据不能永久存储
单列集合 Collection
双列集合Map
单列集合体系结构
单列集合
Collection<>
创建Collection<E>集合对象
Collection<E> 集合名 = new 具体的实现类对象<E>();
例如 :
Collection<E> 集合名 = new ArrayList<E>();
Collection<E> 集合名 = new HashSet<E>();
*boolean add(E e) : 添加元素,返回添加是否成功
删 :
*boolean remove(Object o) : 删除集合中指定元素,返回删除是否成功 -> 按元素值来删
void clear() : 清空集合中所有的元素
改 : Collection因为没有索引所以没有set方法
查 : Collection因为没有索引所以没有get方法
boolean contains(Object o) : 查询传入元素是否包含于集合中
boolean isEmpty() : 查询集合是否为空集合
* int size() : 查询集合中的元素个数/查询集合的长度
遍历方式:
1. 转数组
Object[] toArray()
2. 迭代器 -> 面向对象的遍历方式
Iterator iterator()
3. 增强for循环 (能用迭代器遍历的一定能用增强for)
迭代器 Iterator<>
boolean hasNext(): 查看容器中是否有下一个元素,如果有返回true
E next() : 拿到容器中的下一个元素
迭代器的使用步骤:
1. 获取迭代器对象 :
Iterator<E> it = 单列集合对象.iterator();
2. 循环操作 : 判断集合中是否有下一个元素
3. 如果有,拿到集合的这个元素; 以此往复,直到集合元素全部获取完毕
ConcurrentModificationException:并发修改异常
此异常只在迭代器中发生,触发的条件: 当使用迭代器对象遍历集合的时候,使用集合对象对原集合进行增删改操作都会出这个异常
解决方案:
1. 不修改
2. 使用列表迭代器(ListIterator)对象进行修改
触发时机 : 只要创建了迭代器对象,就不可以使用集合对象修改集合中的元素的内容!!
增强for循环
格式:
// : 后面 -> 要遍历的容器
// : 前面 -> 接收容器数据的变量
for(容器元素类型 变量名:集合对象/数组对象){
//对变量名进行操作 -> 变量接收的就是容器中的元素
}
底层: 增强for循环的底层是一个看不见的迭代器在操作
增强for只用来遍历集合/数组,不在在增强for循环中修改集合内容!!(不要再增强for中写复杂代码)
包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
包装类型有特性:
自动装箱 : 基本数据类型->引用数据类型
Integer i = 100;//Integer i = Integer.valueOf(100);
自动拆箱 : 引用数据类型->基本数据类型
int num = i;//int num = i.intValue();
List<>接口
List<E>接口 : 存取有序 , 元素有索引 , 元素能重复
创建List<E>集合对象
List<E>集合名 = new 具体的实现类对象<E>();
例如 :
List<E> 集合名 = new ArrayList<E>();
List<E> 集合名 = new HashSet<E>(); 错误
增删改查: //List接口中新增关于索引操作的方法
增 :
*boolean add(E e) : 依次添加元素,永远返回true
*void add(int index, E element) : 插入-> 在指定索引位置插入元素
删 :
*boolean remove(Object o) : 删除集合中指定元素,返回删除是否成功 -> 按元素值来删
void clear() : 清空集合中所有的元素
*E remove(int index) : 按照 索引删除指定索引位置的元素,并返回被删除的元素
改 :
E set(int index,E newElement): 修改指定索引位置的元素并返回被修改的元素
查 :
* E get(int index) : 获取指定索引位置的元素
boolean contains(Object o) : 查询传入元素是否包含于集合中
boolean isEmpty() : 查询集合是否为空集合
* int size() : 查询集合中的元素个数/查询集合的长度
int indexOf(Object o) : 获取传入的元素o第一次出现在集合的索引位置
int lastIndexOf(Object o) : 获取传入的元素o最后一次出现在集合的索引位置
遍历方式:
1. 转数组
Object[] toArray()
2. 迭代器 -> 面向对象的遍历方式
Iterator<E> iterator()
3. 增强for循环 (能用迭代器遍历的一定能用增强for)
4. 普通for循环 for循环 和 get(int index) 和 size()
5. 列表迭代器 ListIterator
ListIterator<E> listIterator()
ListIterator<> 列表迭代器
ListIterator是Iterator接口的子接口!
ListIterator<E>接口中有2个方法:
boolean hasNext(): 查看容器中是否有下一个元素,如果有返回true
E next() : 拿到容器中的下一个元素
迭代器的使用步骤:
1. 获取迭代器对象 :
ListIterator<E> lit = List接口实现对象.listIterator();
2. 循环操作 : 判断集合中是否有下一个元素
3. 如果有,拿到集合的这个元素; 以此往复,直到集合元素全部获取完毕
ArrayList<>
ArrayList<E> : 完美的元素可重复的List接口实现!!
底层数据结构是数组!! 数组结构带来了: 查询快,增删慢!
ArrayList<E>类 : 存取有序 , 元素有索引 , 元素能重复
创建ArrayList<E>集合对象
ArrayList<E> 集合名 = new ArrayList<E>();
增删改查:
增 :
*boolean add(E e) : 依次添加元素,永远返回true
*void add(int index, E element) : 插入-> 在指定索引位置插入元素
删 :
*boolean remove(Object o) : 删除集合中指定元素,返回删除是否成功 -> 按元素值来删
void clear() : 清空集合中所有的元素
*E remove(int index) : 按照 索引删除指定索引位置的元素,并返回被删除的元素
改 :
E set(int index,E newElement): 修改指定索引位置的元素并返回被修改的元素
查 :
* E get(int index) : 获取指定索引位置的元素
boolean contains(Object o) : 查询传入元素是否包含于集合中
boolean isEmpty() : 查询集合是否为空集合
* int size() : 查询集合中的元素个数/查询集合的长度
int indexOf(Object o) : 获取传入的元素o第一次出现在集合的索引位置
int lastIndexOf(Object o) : 获取传入的元素o最后一次出现在集合的索引位置
遍历方式:
1. 转数组
Object[] toArray()
2. 迭代器 -> 面向对象的遍历方式
Iterator<E> iterator()
3. 增强for循环 (能用迭代器遍历的一定能用增强for)
4. 普通for循环 for循环 和 get(int index) 和 size()
5. 列表迭代器 ListIterator
ListIterator<E> listIterator()
底层原理
1. 当创建ArrayList集合的时候,代码底层会创建一个长度为0的数组
ArrayList<E> list = new ArrayList<>();
2. 当往ArrayList集合对象中添加第一个元素的时候,底层的数组会重新创建,新创建的数组长度是10
list.add(e对象); //第一次添加元素
3. 往ArrayList集合中添加第11个元素的时候,底层的数组会重新创建,新创建的数组长度是15
list.add(e对象); //第十一次添加元素
规律: 每当集合底层数组容量不够的时候,创建的新数组长度为老数组长度的1.5倍
// newLength = oldLength + (oldLength >> 1)
往ArrayList添加第1024个元素的时候,请问底层数组的长度是多少? 1234
数据结构
代码的本质 : 数据结构 + 算法
集合的本质 : 数据结构 + 数组
栈
- 先进后出
- 存取无序
对列
- 先进先出
- 存取有序
数组
- 查询快 增删慢
- 数组长度一旦被定义长度不能发生改变,如果发生改变一定是生成了新的数组
单相链表
- 效率低
- 只能一个个进栈
- 查询慢 增删快
- 存取有序
双向链表
- 效率低
- 只能一个个进栈
- 查询慢 增删快
- 存取有序
- 比单向链表效率高
- LinkedList集合的底层是双向链表
Set<>集合是接口
-
长度可变
-
只能存引用数据类型(存基本数据类型要存包装类)
-
元素无索引
-
元素不可以重复
-
元素存取无序
创建容器 Set<E> 集合名 = new 实现类<E>();
增删改查
增: boolean add(E e) : 往集合中添加元素,返回元素是否添加成功
删:
boolean remove(Object o) : 按照传入元素值删除集合中的元素,返回删除是否成功
void clear():清空集合中所有的元素
改: 没有索引所以没有set方法
查: 没有索引所以没有get方法
boolean contains(Object o) : 是否包含
boolean isEmpty() : 是否为空集合
int size() : 查询 集合中元素的个数和集合的长度
遍历:
1. 转数组 : 来自于Collection
Object[] toArray();
2. 普通迭代器 : 来自于Collection
Iterator<E> iterator();
3. 增强for
HashSet<>集合
HashSet集合 : 底层数据结构是Hash表的Set集合实现!!
创建容器
HashSet 集合名 = new HashSet();
增删改查
增: boolean add(E e) : 往集合中添加元素,返回元素是否添加成功
删:
boolean remove(Object o) : 按照传入元素值删除集合中的元素,返回删除是否成功
void clear():清空集合中所有的元素
改: 没有索引所以没有set方法
查: 没有索引所以没有get方法
boolean contains(Object o) : 是否包含
boolean isEmpty() : 是否为空集合
int size() : 查询 集合中元素的个数和集合的长度
遍历:
1. 转数组 : 来自于Collection
Object[] toArray();
2. 普通迭代器 : 来自于Collection
Iterator iterator();
3. 增强for
哈希表
HashSet<>集合去重原理
HashSet<E>集合去重原理 :
按照对象的hashCode()方法和equals()方法的编写逻辑进行去重
默认情况 : 类中没有重写hashCode()方法和equals()方法,此类对象存储到HashSet集合中按照元素的地址值去重
如果说想按照对象的属性值进行去重 : 请自动重写hashCode()方法和equals()方法
LinkedHashSet <>
元素不重复 元素无索引 元素存取有序
LinkedHashSet 是 HashSet 的子类;
红黑树
TreeSet<>
TreeSet<E> : 元素不重复,元素可以排序(元素存取无序),元素无索引
常用的对象类型默认排序规则:
整数存储在TreeSet集合中默认升序!!
字符串存在TreeSet集合中默认按照ASCII码升序排序!!
注意事项 : 越靠前的字符ASCII码优先级越高