一、复习
日期解析的方法签名(字符串–>日期)
- Date parse(String s)
日期格式化的方法签名(日期–>字符串)- String format(Date date)
运行时异常有哪些,什么特点- RuntimeException及其子类,编码时不用强制处理
编译期异常有哪些,什么特点- 除了以上的都是,编码时必须强制处理
异常的处理方式哪些,什么区别- 抛出,抛出后代码不再执行
- 捕获,捕获后还可以执行
finally干什么的- 释放资源
throw和throws什么区别- 位置?throw在方法内,throws在方法参数列表()后
- 后面写?throw后跟1个异常对象,throws后面跟多个异常类名
- 作用?throw是抛出异常对象的,throws只是声明可能要抛出异常类型
二、集合框架体系
数组:存储多个数据的容器
- 特性:
- 数组长度固定
- 数组只能存储同一种类型
- 用法只能是通过数组下标取值赋值,用法单一
- 数组内元素可以重复
- 数组内的元素有顺序(存值时的顺序)
集合:存储多个数据的容器
- 特性
- 长度不固定
- 可以存储不同类型
- 集合是一系列的类,可以创建对象,有丰富的方法可以操作数据
- 有些集合可以重复(List),有些集合不允许重复(Set);
- 有些集合是有序的(List),有些集合是无序的(HashSet)
- 有些集合还会排序(TreeSet)
- Collection是集合层次的父接口,定义了所有集合共性操作
- Collection有两个常用接口:List,Set
- List接口集合,主要特征:有序,允许重复
- Set接口,主要特征;允许重复,有序要看子实现类
- List接口有两个常用实现类
- ArrayList,底层是数组,也是允许元素重复,数据有序
- LinkedList,底层是链表,也是允许元素重复,数据有序
- Set接口有两个常用实现类
- HashSet,底层是hash表,存储的元素无序且去重
- TreeSet,底层是二叉树,存储的元素是排序且去重
二、Collection、List介绍
- Collection父接口
- 定义了一部分集合的共性操作,并不全
- List是COllection的子接口,有序允许重复的集合
- 定义了一些方法,可以对位置进行精准控制
- 即可以按照下标插入,删除,查询,修改集合元素
- List是接口,不能直接用,常用使其子实现类,ArrayList和LinkedList
三、ArrayList
3.1 演示方法
3.1.1 演示部分方法,主要对集合元素
增删改查
package com.qf;
import java.util.ArrayList;
/**
* Fighting!!!
*
* @author LiWenJing
* @desc
* @since 2024/3/8 10:50
*/
public class Demo1_ArrayList {
public static void main(String[] args) {
ArrayList list = new ArrayList();
//增
list.add(1);
list.add(7);
list.add(5);
System.out.println("初始化:"+list);
//删
list.remove(0);
System.out.println("删后:"+list);
//改
list.set(0,6);
System.out.println("改后:"+list);
//查
Object o = list.get(1);
System.out.println("查:"+o);
}
}
四、泛型
4.1 了解泛型
public class Demo1_ArrayList {
public static void main(String[] args) {
/**
*泛型:
* 通过在类名后,指定泛型类型,从而确定该集合只能存储指定类型
* 泛型的好处:
* 1)约束数据类型
* 2)减少类型转换,特别是强转
*/
ArrayList<Integer> list2 = new ArrayList<>();
//有了泛型约束,存储时只能是Integer
list2.add(1);
list2.add(2);
list2.add(3);
//有了泛型约束,取值时直接时Integer,无需转换
Integer i = list2.get(2);
}
}
4.2 使用泛型后对集合元素进行
增删改查
package com.qf;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Fighting!!!
*
* @author LiWenJing
* @desc
* @since 2024/3/8 10:50
*/
public class Demo1_ArrayList {
public static void main(String[] args) {
show3();
}
//使用泛型对集合元素进行增删改查
private static void show3() {
ArrayList<Integer> list3 = new ArrayList<>();
//增
list3.add(1);
list3.add(4);
list3.add(9);
list3.add(5);
list3.add(8);
list3.add(2);
System.out.println("初始化:"+list3);
//删
list3.remove(0);
System.out.println("删后:"+list3);
//改
list3.set(0,1);
System.out.println("改后:"+list3);
//查
Integer i = list3.get(0);
System.out.println("查:"+i);
// addAll方法
ArrayList<Integer> list4 = new ArrayList<>();
list4.add(12);
list4.add(13);
list4.add(14);
list3.addAll(2,list4);
System.out.println("addAll后:"+list3);
//removeAll,在一个集合里删除与另一个集合相同的元素
list3.removeAll(list4);
System.out.println("removeAll后:"+list3);
//存储元素的个数
int size = list3.size();
System.out.println("集合元素个数:"+size);
//判断集合是否包含某个元素
System.out.println("是否包含某个元素:"+list3.contains(5));
//toArray方法
//1.先创建整型数组
Integer[] integers = new Integer[list3.size()];
Integer[] array = list3.toArray(integers);
System.out.println(Arrays.toString(array));
// 清空全部元素
list3.clear();
System.out.println("清空后:"+list3);
//判断集合是否为空
boolean empty = list3.isEmpty();
System.out.println(empty);
}
}
五、迭代
package com.qf;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
/**
* Fighting!!!
*
* @author LiWenJing
* @desc
* @since 2024/3/8 10:50
*/
public class Demo1_ArrayList {
public static void main(String[] args) {
/**
* 使用迭代器遍历
*/
ArrayList<Integer> list5 = new ArrayList<>();
list5.add(1);
list5.add(4);
list5.add(2);
list5.add(3);
//1)获得迭代器
// Iterator<Integer> it = list5.iterator();
//2)遍历迭代器
// while(it.hasNext()){ //判断有无下一个元素
// Integer next = it.next();//取出下一个元素
// System.out.println(next);
// }
//迭代器的简化写法:增强for循环,也叫foreach
/** 【结果】
* for(数据类型 变量: 集合)
*/
for (Integer i : list5) {
System.out.println(i);
}
//遍历数组
int[] arr = {1,2,3,4};
for (int i : arr) {
System.out.println(i);
}
}
}
5.2 底层原理[面试]
- ArrayList底层是数组实现的
- 起始容量(数组长度)默认是10
- 刚new完创建的空集合的,容量是0
- 当第一次加入元素的时候,数组容量扩容为10
- 当元素放满10个时,当加入第11个时候会触发扩容,扩容为原来的1.5倍(通过>>1 右移一位算出来)
- 扩容为1.5倍后,再把原数组的元素拷贝到新数组
使用上效率问题:
- ArrayList进行元素的查询,修改速度快
- 但是进行元素的插入和删除速度慢
原因:
- 数组在内存是连续空间,有下标
- 所以,通过下标直接定位找到元素,改变该位置元素(所以:查询和更新快)
- 正是因为内存空间问题,插入或删除一个数据时,从插入/删除位置开始后续的元素需要后移或者前移一位(牵一发动全身,所以插入删除慢)
六、LinkedList
6.1 方法演示与ArrayList方法一样
LinkedList也是List实现类,也是允许元素重复,有序的集合
6.2 特殊方法
除了基本的方法与ArrayList一样之外,LinkedList还提供一些比较特殊的操作头尾的方法
- getFirst getLast
- removeFirst removeLast
- addFirst addLast
6.3 底层原理
LinkedList底层是双向链表
- 链表再内存中是不连续的
- 通过链域里面记录上一个/下一个元素的位置
当通过下标找寻一个元素的时候,并不是直接定位的,是从头或者尾开始一个一个遍历查找对应的元素,也正是因为如此,所以提供了专门操作头尾的方法的,可以直接定位到,方便操作。
也正因为空间数据结构的问题,导致了一些特性
- LinkedList查询,更新数据慢
- LinkedList插入,删除数据快(因为插入或删除元素改变的知识链域的记录信息,没有改变其他元素位置)
st removeLast- addFirst addLast
6.3 底层原理
LinkedList底层是双向链表
- 链表再内存中是不连续的
- 通过链域里面记录上一个/下一个元素的位置
当通过下标找寻一个元素的时候,并不是直接定位的,是从头或者尾开始一个一个遍历查找对应的元素,也正是因为如此,所以提供了专门操作头尾的方法的,可以直接定位到,方便操作。
也正因为空间数据结构的问题,导致了一些特性
- LinkedList查询,更新数据慢
- LinkedList插入,删除数据快(因为插入或删除元素改变的知识链域的记录信息,没有改变其他元素位置)
练习题:
package com.qf;
import jdk.nashorn.internal.runtime.ListAdapter;
import java.util.ArrayList;
import java.util.Scanner;
/**
* Fighting!!!
*
* @author LiWenJing
* @desc
* @since 2024/3/8 19:09
*/
public class Demo2_ArrayList {
public static void main(String[] args) {
System.out.println("--------------欢迎来到点歌系统--------------");
System.out.println("0.添加歌曲至列表");
System.out.println("1.将歌曲置顶");
System.out.println("2.将歌曲前移一位");
System.out.println("3.退出");
ArrayList<String> list = new ArrayList<>();
list.add("奇迹再现");
list.add("夜空中最亮的心");
list.add("姐就是女王");
list.add("甜蜜蜜");
list.add("月半小夜曲");
System.out.println("初始歌曲列表:"+list);
Scanner sc = new Scanner(System.in);
while (true){
System.out.println();
System.out.print("请输入要执行的操作序号:");
int i = sc.nextInt();
switch (i){
case 0:
System.out.print("请输入要添加的歌曲名称:");
String s3 = sc.next();
if(!list.contains(s3)){
list.add(s3);
System.out.println("已添加歌曲:"+s3);
System.out.println("当前歌曲列表:"+list);
break;
}else {
System.out.println("歌曲已存在,不能重复添加");
break;
}
case 1:
System.out.print("请输入要置顶的歌曲名称:");
String s = sc.next();
if(list.contains(s)){
int index = list.indexOf(s);
System.out.println(index);
list.remove(index);
list.add(0,s);
System.out.println("已将歌曲"+s+"置顶");
System.out.println("当前歌曲列表:"+list);
break;
}else {
System.out.println("歌曲列表不存在"+s+",无法置顶");
break;
}
case 2:
System.out.println("请输入要置前的歌曲名称:");
String s2 = sc.next();
if(list.contains(s2)){
int index = list.indexOf(s2);
list.remove(index);
list.add(index-1,s2);
System.out.println("已将歌曲"+s2+"置前一位");
System.out.println("当前歌曲列表:"+list);
break;
}else {
System.out.println("歌曲列表不存在"+s2+",无法置前");
break;
}
case 3:
System.out.println("---------退出---------");
System.out.println("您已退出系统");
return;
default:
System.out.println("没有您要访问的业务");
break;
}
}
}
}