06|「常用容器与异常 」

文章详细介绍了Java中的常用容器,包括List接口的ArrayList和LinkedList实现,Set接口的HashSet和TreeSet实现,以及Map接口的HashMap和TreeMap实现。同时,文章讲解了异常处理的基本概念,区分了Error和Exception,概述了异常的分类及捕获、抛出异常的机制,并给出了try-catch-finally的使用示例。

前言

常用容器与异常

一、前置知识

  • 接口的多态
  • 接口
  • 接口的实现(类)

二、常用容器

  • 接口:定义了必须要实现的函数;
  • 实现:用类来实现接口中函数的具体的逻辑;

1、List

  • List 是一个接口
  • 实现:ArrayList :变长数组,LinkList:双链表
  • ArrayList 与 LinkList 的区别(什么时候用):ArrayList 支持随机寻址,即可以通过索引快速访问元素,但插入和删除操作(尤其是在中间位置)相对较慢。
  • LinkedList不支持随机寻址,插入和删除操作(尤其是在已知节点的情况下)相对较快,但访问特定位置的元素需要从头节点开始遍历。
  • API:

2、Set

  • 维护的是一个集合;
  • 实现:
    • HashSet 哈希表:用来判断一个数是否存在,是无序的,插入、删除、查询、修改均为 O(1) 时间复杂度;
    • TreeSet 平衡树:用来动态维护一个有序序列;插入、删除、查询、修改均为 O(log n) 时间复杂度,以 2 为底;
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
// 便利set
for (int x : set)
	System.out.println(x);

3、Map

  • 维护的是一个映射,映射是将一个元素映射到另外一个元素;

  • 实现

    • HashMap<K, V>: 哈希表,无序
    • TreeMap<K, V>:平衡树,有序
    Map<String, Integer> map = new HashMap<>();
    map.put("123", 2);
    map.put("321", 3);
    map.put("21", 10);
    
    // 遍历
    for (Map.Entry<String, Integer> entry: map.entrySet())
    	System.out.println("%s %d\n", entry.getKey(), entry.getValue());
    

三、异常

1、异常处理和 Error 的区别

Error (错误):超内存、线程死亡等错误导致程序无法继续执行,不可修复的,会报 Error 错误;
Exception(异常):出现错误,可修复(出现错误以后,通过增加判断提示给用户)。例如,用户访问数组时数组越界,通过增加判断提示给用户,让用户重新输入,无需中断整个程序;

2、异常的继承关系

在这里插入图片描述

3、异常的分类

1)运行时异常

  • 运行时异常都是 RuntimeException 类及其子类异常;
  • 例如,数组越界异常、空指针异常 ;这些异常是非检查型异常,程序中可以选择捕获处理,也可以不捕获处理
  • 这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;

2)其它异常

  • 另外一种异常:除了运行时异常以外的异常,这类异常被称为检查型异常,类型上都属于 Exception 类及其子类;
  • 从程序语法角度讲是必须进行捕获处理的异常,如果不处理,程序就不能编译通过(这类异常如果被抛出,需要在外面对其进行捕获或者继续往外抛,不能不处理);

3、捕获异常

  • try:可能出异常的代码,可写多句;代码会一行一行执行,当其中某一行出现异常时,匹配 catch 中异常的情况,如果 catch 中没有任何一个匹配的,就会抛出这个异常(程序会终止,但是 finally 中的代码会执行);
  • catch:用于匹配出异常的情况;
  • finally:无论有没有报异常都需要执行的代码,放到 finally 中(finally 中的代码无论如何都会执行);
public class Main {

    private static void foo() {
        int[] array = new int[5];
        for (int i = 0; i < 5; i ++ )
            array[i] = i;

        Scanner sc = new Scanner(System.in);
        int k = sc.nextInt();
        int x = sc.nextInt();

        try {
            array[k] /= x;
        } catch (ArithmeticException e) {
            System.out.println("除零错误!");
            e.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界!");
            e.printStackTrace();
        } finally {
            for (int i = 0; i < 5; i ++ ) {
                System.out.println(array[i]);
            }
        }
    }

    public static void main(String[] args) {
        foo();
    }
}
  • finally 里面的代码和放到最后的区别
    • return 之后的不会执行,finally 任何情况都会执行;

在这里插入图片描述
在这里插入图片描述

4、抛出异常

  • 什么是抛出异常:如果不捕获异常的话,代码就会直接终止,会将异常抛出(显示报错信息);
    在这里插入图片描述

  • throw:在函数内抛出一个异常,后面只能跟一个异常

  • throws:在函数定义时抛出一些可能的异常,函数内的异常不处理,丢到外层(调用函数的地方)去处理;

  • 对于异常,要么抛出,要么捕获;throws 后面可以跟多个异常;

  • 所有检查型异常,编译器会自动判断报错,必须需要人为要处理,处理的方式有两种(一种是捕获它,另一种方式是抛出(不处理,用 throws ))

1)在函数内,自己抛出一个异常,自己捕获

在这里插入图片描述

2)在函数内直接抛出,在函数内不捕获处理,放到函数外处理,需要函数定义处增加 throws 关键字,声明方法可能抛出的异常类型;
在这里插入图片描述
在这里插入图片描述

在 foo() 方法的声明中,使用了 throws IOException, NoSuchFieldException,表示 foo() 方法有可能会抛出 IOException 或 NoSuchFieldException 类型的异常。
当一个方法可能抛出异常时,可以使用 throws 声明,以通知调用该方法的程序员需要处理这些异常,否则编译器会报错。
在 main() 方法中调用 foo() 方法时,由于 foo() 方法声明了可能抛出异常,所以需要在调用处使用 try-catch 块来捕获可能抛出的异常。

一个函数内可以抛多个异常
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个写代码的修车工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值