异常
Java的异常体系
- Java.lang.Throwable
- Error:代表的系统级别错误(属于严重问题),也就是说系统一旦出现问题,sun公司会把这些问题封装为Error对象给出来。
- Exception:叫异常:它代表的才是我们程序可能出现的问题,所以通常会用Exception以及它的孩子来封装程序出现的问题。
- 运行时异常:RuntimeException及其子类,编译阶段不会出现错误提醒,运行时出现的异常
- 编译时异常:“其他异常…” 编译阶段就会出现错误提醒的。
- 抛出异常(throws)
- 在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理。
方法 throws 异常1 ,异常2 ,异常3 ..{
…
}
try{
}catch(异常类型1 变量){
}catch(异常类型2 变量){
}...
异常的作用
- 异常使用来定位程序bug的关键信息。
- 可以作为方法内部的一种特殊返回值,以便通知上层调用者,方法的执行问题。
自定义异常
- Java无法为这个世界上全部的问题都提供异常类来代表, 如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了。
- 自定义运行时异常
- 定义一个异常继承RuntimeException。
- 重写构造器。
- 通过 throw new 异常类(xxx)来创建异常对象抛出
- 特点:编译阶段不报错,运行时才可能出现,提醒不属于激进型。
- 自定义编译时异常
- 定义一个异常继承Exception。
- 重写构造器。
- 通过 throw new 异常类(xxx)创建异常对象并抛出。
- 特点:编译阶段就报错,提醒比较激进。
异常的处理方案
- 方案一:底层异常层层往上抛出,最外层捕获异常,记录下异常信息,并响应适合用户观看的信息进行提示。
- 方案二:最外层捕获异常后,尝试重新修复。
异常的两种处理方式
方法 throws 异常1 ,异常2 ,异常3 ..{
…
}
try{
}catch(异常类型1 变量){
}catch(异常类型2 变量){
}...
泛型
- 定义类、接口、方法是,同时声明了一个或多个类型变量(如:)
public class ArrayList<E>{
. . .
}
- 作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力. 这样可以避免强制类型转换,及其可能出现的异常。
- 泛型的本质:把具体的数据类型作为参数给类型变量。
泛型类
修饰符 class 类名<类型变量,类型变量,…> {
}
- 类型变量建议用大写的英文字母,常用的有:E、T、K、V 等
泛型接口
修饰符 interface 接口名<类型变量,类型变量,…> {
}
泛型方法、通配符和上下限
修饰符 <类型变量,类型变量,…> 返回值类型 方法名(形参列表) {
}
- 通配符
- 就是 “?”,可以在 “使用泛型” 的时候代表一切类型; E T K V 是在定义泛型的时候使用。
- 泛型的上下限:
- 泛型上限:? extends Car: ? 能接收的必须是Car或者其子类 。
- 泛型下限:? super Car:? 能接收的必须是Car或者其父类。
泛型支持的类型
- 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。
集合框架
- 集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用。
集合体系结构
- Collection 代表单列集合,每个元素(数据)只包括一个值。
- Map 代表双列集合,每个元素包含两个值(键值对)。
Collection
- Collection
- Collection集合特点
- List系列集合:添加的元素是有序、可重复、有索引。
- ArrayList、LinekdList:有序、可重复、无索引。
- Set系列集合:添加的元素是无序、不重复、无索引。
- HashSet:无序、不重复、无索引。
- LinkedHashSet:有序、不重复、无索引。
- TreeSet:按照大小默认升序排序、不重复、无索引。
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() |
把集合中的元素,存储到数组中 |
Collection的遍历方式
- 迭代器遍历
- 迭代器是用来遍历集合的专用方式(数组没有迭代器),在Java中迭代器的代表是Iterator。
方法名称 |
说明 |
Iterator iterator() |
返回集合中的迭代器对象,该迭代器对象默认指向当前集合的第一个元素 |
方法名称 |
说明 |
boolean hasNext() |
询问当前位置是否有元素存在,存在返回true ,不存在返回false |
E next() |
获取当前位置的元素,并同时将迭代器对象指向下一个元素处。 |
- 增强 for 循环
- 增强for可以用来遍历集合或者数组
- 增强for遍历集合,本质就是迭代器遍历集合的简化写法。
for (元素的数据类型 变量名 : 数组或者集合) {
}
- Lambda表达式
- JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。
方法名称 |
说明 |
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);
}
});
Collection<String> lists = new ArrayList<>();
...
lists.forEach(s -> {
System.out.println(s);
});
认识并发修改异常问题
- 遍历集合的同时又存在增删集合元素的行为时可能出现业务异常,这种现象被称之为并发修改异常问题。
解决并发修改异常问题的方案
- 如果集合支持索引,可以使用for循环遍历,每删除数据后做 i–;或者可以倒着遍历。
- 可以使用迭代器遍历,并用迭代器提供的删除方法删除数据。
- 增强for循环/Lambda遍历均不能解决并发修改异常问题,因此增它们只适合做数据的遍历,不适合同时做增删操作。
List集合
- ArrayList和LinkedList,底层实现不同,适应的场景不同。
List集合的特有方法
- List集合因为支持索引,所以多了很多与索引相关的方法。
方法名称 |
说明 |
void add(int index,E element) |
在此集合中的指定位置插入指定的元素 |
E remove(int index) |
删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) |
修改指定索引处的元素,返回被修改的元素 |
E get(int index) |
返回指定索引处的元素 |
- List集合支持的遍历方式
- for循环
- 迭代器
- 增强for循环
- Lambda表达式
ArrayList底层原理
- ArrayList底层是基于数组存储数据的。
- 数组的特点
LinkedList的底层原理
- LinkedList底层是基于链表存储数据的。
- 基于双链表实现的。
- 特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。
- 链表的特点:
- 链表中的数据是一个一个独立的结点组成的,结点在内存中是不连续的,每个结点包含数据值和下一个结点的地址。
- 查询慢,无论查询哪个数据都要从头开始找。
- 链表增删相对快.
- 双链表:对首尾元素进行增删改查的速度是极快的。
- LinkedList新增了很多首尾操作的特有方法。
方法名称 |
说明 |
public void addFirst(E e) |
在该列表开头插入指定的元素 |
public void addLast(E e) |
将指定的元素追加到此列表的末尾 |
public E getFirst() |
返回此列表中的第一个元素 |
public E getLast() |
返回此列表中的最后一个元素 |
public E removeFirst() |
从此列表中删除并返回第一个元素 |
public E removeLast() |
从此列表中删除并返回最后一个元素 |
LinkedList的应用场景
- 用来设计队列
- 用来设计栈
- 栈的特点:后进先出,先进后出。
- 数据进入栈模型的过程称为:压/进栈(push)
- 数据离开栈模型的过程称为:弹/出栈(pop)
- 使用首尾元素,用Linked来实现很合适。