1 List集合
- 概述:List集合是Collection接口下的子接口
- 特点:
(1)属于一个单列集合
(2)不能直接创建对象,可以通过实现类创建对象
(3)该集合中的元素特点:
有序:元素存入的和取出的顺序可以保证一致
有索引:每个元素都有自己的一个位置,通过有序的序号来表示这个位置,索引
可重复:集合中可以存储相同的元素值
1.1 List集合特殊的方法
函数名 | 解释 |
| 往集合中的指定位置添加元素 |
| 获取集合中指定元素的值 |
| 删除指定位置的元素 |
| 修改集合中指定位置的元素值为ele |
代码
package demos3_list;
import java.util.ArrayList;
import java.util.List;
public class Demo01 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
list.add("xyz");
list.add("aaa");
list.add("123");
System.out.println(list);
//在指定索引上添加元素
list.add(0,"qwer");
System.out.println(list);
//删除指定索引上的元素
list.remove(1);
System.out.println(list);
//获取指定索引对应的元素
System.out.println(list.get(2));
//将指定索引上的元素替换为新元素
list.set(2,"abcd");
System.out.println(list);
}
}
2 List集合遍历元素的总结
package demos3_list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class Demo02 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(“abc”);
list.add(“xyz”);
list.add(“123”);
list.add(“aaa”);
//转数组
Object[] obs = list.toArray();
for (int i = 0; i < obs.length; i++) {
System.out.println(obs[i]);
}
//迭代器遍历
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//增强for遍历
for(Object o:list){
System.out.println(o);
}
//List集合特有的遍历方式:
for(int i = 0;i <= list.size()-1;i++){
System.out.println(list.get(i));
}
}
}
3 并发修改异常
- ConcurrentModificationException
并发 修改 异常 - 出现异常的原因:
使用迭代器对象遍历集合的同时,使用了集合对象增加或者删除元素 - 解决:
使用集合对象遍历,使用集合对象增加元素
使用迭代器对象遍历,使用迭代器对象增加元素 - 使用集合对象遍历,使用集合增加
使用list集合特有的方式遍历
使用集合中的add或者remove方法增加或者删除 - 使用迭代器遍历,使用迭代器增加
(1)iterator()方法获取迭代器对象中只能使用删除方法,不能使用增加方法
(2)如果需要使用迭代器对象增加元素,可以使用List集合特有的方式来获取迭代器
对象: 获取方式:listIterator()
add(E e) 添加元素
remove() 移除元素
代码
package demos3_list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class Demo03 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(111);//自动装箱 Integer
list.add(666);
list.add(888);
list.add(999);
//使用迭代器遍历集合,使用迭代器增加或者删除元素
//避免出现并发修改异常
ListIterator it = list.listIterator();
while(it.hasNext()){
Object o = it.next();
if(o.equals(999)){
it.add(0);
}
}
System.out.println(list);
}
//使用集合对象遍历,使用集合对象增加或者删除元素
//避免出现并发修改异常
private static void test02(List list) {
for(int i = 0; i <= list.size()-1; i++){
Object o = list.get(i);
if(o.equals(999)){
list.add(0);
}
}
System.out.println(list);
}
//一边使用迭代器遍历集合,一边使用集合对象增加或者删除元素
//出现并发修改异常
private static void test(List list) {
Iterator it = list.iterator();
while(it.hasNext()){
Object o = it.next();//Object o = new Integer(999)
//equals方法比较的是属性值不是地址值
if(o.equals(999)){
list.add(0);
}
}
System.out.println(list);
}
}
4 数据结构概述
4.1 栈
- 栈概述:stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。
- 特点: 先进后出,后进先出
元素先存储栈,后取出
元素后存储栈,先取出 - 相关术语:
存入元素:进栈,压栈
取出元素:出栈,弹栈 - 图示理解:
4.2 队列
- 概述:queue,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在 表的一端进行插入,而在表的另一端进行删除。
- 特点:
(1)先进先出,后进后出
(2)队列的入口、出口各占一侧。 - 相关术语:
存入元素:入队
取出元素:出队 - 图示:
4.3 数组
- Array:是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素。
- 特点:
(1)数组存储元素的空间,在内存中是相邻连续的,所以数组中的元素是有序的
(2)数组存储元素,查询元素的效率高:
数组中的每个元素都有一个索引来表示,每个元素占据的空间都是相同的。如果需要查询某一个元素(x),直接通过一次计算就可以获取x元素的地址,从而获取该元素。
(3)数组存储元素,增加删除元素效率低:
增加元素效率低:
因为数组的空间是固定的,如果需要增加一个元素,并且数组的已经没有多余的位置,这时就会重新创建一个扩容后的数组,再将原数组中的元素拷贝到新 数组中,最后将需要添加的元素添加到指定位置。
删除元素效率低:
如果需要删除某一个索引上的一个元素,那该索引后的元素都需要向上挪动,该索引后的元素越多,效率越低
4.4 链表
- 链表:linkedlist,链表中的每一个元素(节点)都是有一个Node对象组成
- 特点:
(1)每一个节点由两部分组成:数据域、指针域
(2)节点之间也是有序连接,所以链表存储元素也是有序的
(3)链表查询元素效率低:
如果需要查询某一个元素(x),需要从头节点开始逐个往后查找,直到查询到x元素位置;x元素前面的数据越多,查询效率越低。
(4)链表增加或者删除元素效率高:
如果需要在x元素和y元素之间增加一个元素,只需要将x元素记录的下一个元素地址值改为新元素地址即可。
如果需要删除某一个元素,只需要将该元素前面的元素记录的地址值修改即可
(5)链表由单向链表,也有双向链表
单向链表:每一个节点中,只保存一个元素和记录下一个元素地址
双向链表:每一个节点中,不仅保存一个元素,还记录该元素上一个和下一个节点地址
5 List的实现类
- 概述:List集合也是一个接口,根据底层存储数据方式的不同有不同的实现类
- 分类:
ArrayList
LinkedList
5.1ArrayList
- List集合的实现类,本类没有特殊的方法,只能使用接口中定义的方法
- 特点:
(1)底层数组实现,可以表示元素有序
(2)查询元素的效率高,增删元素的效率低
代码
package demos3_list;
import java.util.ArrayList;
public class Demo04 {
public static void main(String[] args) {
//1、通过空参构造创建一个arraylist集合,底层就维护了一个空Object数组
//2、如果想要在空的数组中新增第一个元素,将维护的数组大小扩充为10
//3、如果集合中维护的数组空间不够用
// 将数组进行扩容,扩容为原有容量的1.5倍
// 如果扩容之后,还不够存,需要几个空间,将容量扩容为几
ArrayList al = new ArrayList();
al.add("abc");
//在创建一个集合的时候,指定该集合中数组的容量
ArrayList al2 = new ArrayList(20);
}
}
5.2 LinkedList
- 属于List接口的实现类,可以使用接口中继承方法
- 特点:
(1)底层通过双向链表实现,可以保证元素有序
(2)查询元素效率低,增删元素效率高 - 特有方法:因为linkedList可以记录头部和尾部元素的地址,所以有一些操作头部和尾部元素的方法:
函数名 | 解释 |
| 在头部位置添加元素 |
| 在尾部添加元素 |
| 删除头部位置的元素 |
| 删除尾部的元素 |
| 获取头部元素 |
| 获取尾部元素 |
代码
package demos3_list;
import java.util.LinkedList;
public class Demo05 {
public static void main(String[] args) {
LinkedList lin = new LinkedList();
lin.add("abc");
lin.add("xyz");
lin.add("123");
lin.add("456");
//在首节点添加一个元素
lin.addFirst("111");
//在尾结点添加一个元素
lin.addLast("999");
System.out.println(lin);
//获取第一个节点
System.out.println(lin.getFirst());
//获取最后一个节点
System.out.println(lin.getLast());
//删除头节点
lin.removeFirst();
//删除尾节点
lin.removeLast();
System.out.println(lin);
}
}
6 总结
Collection:单列集合的底层接口
常用的方法
遍历集合的方式
List:Collection接口的子接口
元素有序 元素有索引 元素可以重复
特殊的方法:通过索引操作元素
特殊的遍历方式:先获取索引,再通过get方法
并发修改异常
原因:一边使用迭代器遍历集合,一边使用集合对象增加或者删除元素
解决:使用迭代器遍历,迭代器增加 使用集合遍历,集合增加删除
ArrayList:List接口的实现类 特点和接口一样
底层使用动态数组实现
查询元素块,增删元素慢
LinkedList:List接口的实现类 特点和接口一样
底层使用双向链表实现
查询慢,增删快