集合及异常处理
回顾
-
Collection—
-
List—可重复,有序
Set—无序,不可重复
-
List的实现类
ArrayList
Vector
LinkedList
ArrayList,Vector的异同点:都是数组的存储结构,遍历效率高,增删效率低
ArrayList非线程安全(操作效率高),Vector线程安全(效率低)
ArrayList、LinkedList的异同点:
存储结构:ArrayList是数组存储结构,LinkedList是双向链表的存储结构
增删效率:ArrayList效率低,LinkedList效率高
遍历效率:ArrayList效率高,LinkedList效率低
-
从源码角度分析:ArrayList如何添加数据的
- 判断数组容量是否足够:size+1和数组长度对比,扩容:扩容后的数组长度1.5倍 数组赋值
- 把元素存入到数组中的size位置
- size++;
-
如何给集合排序
Collections.sort()排序
排序方式1: Collections.sort(list,new Comparator(){
public int compare(Student o1,Studeng o2){
return o1.getXXX()-o2.getXXX)();
}
});
排序方式2: Student implements Comparable{
public int compareTo(Studentstudent o){
return this.age-o.age;
}
}
Collections.sort(list);
Set: HashSet LinkedHashSet TreeSet
HashSet 存储学生对象
今日内容
- LinkedHashSet
- TreeSet
- Map的组成
- HashMap TreeMap的使用
LinkedHashSet
特点:唯一 hashCode()
有序 链表结构
public class Demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> sets=new LinkedHashSet<String>();
sets.add("zzz");
sets.add("ccc");
sets.add("jjj");
for(String str:sets)
System.out.println(str);
}
}
SortedSet 接口的实现类TreeSet
数据结构—数组 树(二叉树 平衡二叉树 B+树) 队列(先进先出) 堆栈(先进后出)
TreeSet里面存的对象必须实现Comparable接口
【结论】:HashSet不能排序,TreeSet在类实现时Comparable接口后自动排序
public class Student implements Comparable<Student>{
private String stuNo;
private String stuName;
private int age;
public String getStuNo() {
return stuNo;
}
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String stuNo, String stuName, int age) {
super();
this.stuNo = stuNo;
this.stuName = stuName;
this.age = age;
}
public Student() {
super();
}
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
return this.stuNo.compareTo(o.stuNo);
}
}
public class Demo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Student> stus = new TreeSet<Student>();
Student s1=new Student("001","张三",24);
Student s2=new Student("002","李四",35);
Student s3=new Student("003","王五",12);
Student s4=new Student("004","赵六",19);
stus.add(s1);
stus.add(s2);
stus.add(s3);
stus.add(s4);
for(Student stu:stus)
System.out.println(stu);
}
}
Map接口的实现类 HashMap 重点
HashMap 底层是哈希表-----数组+单链表(如果单链表的长度超过8,转为红黑树)
存储形式:key键-value值 对象
通过对key来确定在哈希表的存储额外i之—key唯一,如果重复,value值发生覆盖
HashTable:哈希表存储结构 —线程安全,效率低,不允许null作为key或value
HashMap: 哈希表存储结构 ----非线程安全,效率高,允许null作为value
4.异常
程序运行过程中的非正常情况,导致程序无法继续运行。
对异常进行处理,保障程序能够继续运行。
异常的父类:Throwable
异常的分类:
- 错误Error:软件(JVM)或硬件出现的问题,程序的逻辑 无法手动处理
- 异常Exception:程序在运行过程中产生的问题。
Exception分两种类型:
- 运行时异常 RuntimeException:程序运行过程中产生,可以选择性处理
- 受查异常:CheckedException:必须处理此类一场,否则程序无法编译运行
解决方式1:捕获
try{
//可能会发生异常的代码
}catch(异常类型 对象名){
//catch捕获try中产生的和catch中类型相同的或是其子类的异常
//提示异常信息给用户,后续的代码会继续执行。
}finally{
//无论有无异常,无论一场是否被捕捉到,都能被执行的语句块。
}
【说明】:在catch中不要直接使用Exception进行捕获,不能明确具体的异常原因,建议使用多路捕获
【注意】:在多路catch捕获异常时,异常的类型一定是要子类在先父类在后。
解决方式2:抛出异常
public class Test {
// throws 抛出异常,把方法体内差生的异常抛给方法的调用者
public int com(int num1,int num2) throws ArithmeticException{
int result=num1/num2;
return result;
}
}
5.自定义异常
当不符合自定义的业务时,可以手动创建异常对象,然后抛出这个异常
package com.qf.pro2103.day17;
public class PriceException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public PriceException(){
}
public PriceException(String meg){
super(meg);
}
}
package com.qf.pro2103.day17;
public class Test {
// throws 抛出异常,把方法体内差生的异常抛给方法的调用者
public int com(int num1,int num2) throws ArithmeticException{
int result=num1/num2;
return result;
}
public void pay(int money)throws PriceException{
if(money<0){
//手动创建异常对象
throw new PriceException("你输入的金额数不正确!");
}else{
System.out.println("付款成功!付款金额为:"+money);
}
}
}
public class Demo12 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=new Test();
try {
test.pay(-10);
} catch (PriceException e) {
// TODO Auto-generated catch block
System.out.println("发生异常,异常原因为:"+e.getMessage());
//打印方法调用过程产生的所有异常
//e.printStackTrace();
}
}
}
总结
异常处理有两种
-
捕获异常:try-catch
-
抛出异常:throw-throws
throw,用在方法内部,作用时抛出一个异常 throw new PriceException(“你输入的金额数不正确”);
throws,用在方法的)后面,作用是限定抛出的异常类型
public int com(int num1,int num2) throws ArithmeticException{
自定义异常
- 新建自定义异常类,继承Exception或某个子类
- 重载构造方法,在有参构造方法中,通过参数传递异常信息
多路捕获异常:catch异常
异常:Exception:getMessage(); 返回字符串:异常信息
printStackTrace() 打印方法调用过程中,异常的传递
finally:无论有无异常,无论能否捕获到,都能被执行的代码----常用于关闭资源
的金额数不正确");
throws,用在方法的)后面,作用是限定抛出的异常类型
public int com(int num1,int num2) throws ArithmeticException{
自定义异常
- 新建自定义异常类,继承Exception或某个子类
- 重载构造方法,在有参构造方法中,通过参数传递异常信息
多路捕获异常:catch异常
异常:Exception:getMessage(); 返回字符串:异常信息
printStackTrace() 打印方法调用过程中,异常的传递
finally:无论有无异常,无论能否捕获到,都能被执行的代码----常用于关闭资源