day09 异常、泛型、集合框架

目录

1.异常

1.1认识异常

1.1.1异常是什么

1.1.2异常的分类

1.1.3异常的基本处理

1.1.4异常的作用

1.2自定义异常

1.2.1为什么自定义异常

1.2.2两种自定义异常

1.3最常见的异常处理方案 

2.泛型

2.1认识泛型

2.1.1什么是泛型

2.1.2泛型的作用

2.1.3泛型的本质

2.2泛型类

2.2.1格式

2.3泛型接口

2.3.1格式

2.4泛型方法、通配符、上下限

2.4.1泛型方法

2.4.2通配符

2.4.3上下限

2.5泛型支持的类型

2.5.1特点

2.5.2包装类

2.5.3包装类其他的功能

3.集合框架

3.1认识集合

3.1.1什么是集合

3.1.2集合体系结构

3.1.3Collection集合特点

3.2Collection的功能

3.2.1常用方法

3.2.2三种遍历方式

3.2.3三种遍历方式的区别

3.3List集合

3.3.1List系列集合特点

3.3.2List集合的特有方法

3.3.3List集合支持的遍历方式

3.4ArrayList

3.4.1特点

3.5LinkedList

3.5.1特点

3.5.2 LinkedList的特有方法

3.5.3应用场景 


1.异常

1.1认识异常

1.1.1异常是什么

异常代表程序出现的问题

1.1.2异常的分类

【1】运行时异常

继承自RuntimeException的异常或其子类,编译阶段不报错,运行时出现的。(如:数组索引越界异常)

public static void show(){
        System.out.println("==程序开始。。。。==");
        // 运行时异常的特点:编译阶段不报错,运行时出现的异常,继承自 RuntimeException。
        int[] arr = {1,2,3};
        // System.out.println(arr[3]); // ArrayIndexOutOfBoundsException

        // System.out.println(10/0); // ArithmeticException

        // 空指针异常
        String str = null;
        System.out.println(str);
        System.out.println(str.length()); // NullPointerException

        System.out.println("==程序结束。。。。==");
    }

【2】编译时异常

没有继承RuntimeExcpetion的异常,编译阶段就会出错。(如:日期解析异常)

public static void show2() throws Exception {
        System.out.println("==程序开始。。。。==");
        // 编译异常:编译阶段报错,编译不通过。
        String str = "2024-07-09 11:12:13";
        // 把字符串时间解析成Java中的一个日期对象。
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = sdf.parse(str); // 编译时异常,提醒程序员这里的程序很容易出错,请您注意!
        System.out.println(date);

        InputStream is = new FileInputStream("D:/meinv.png");

        System.out.println("==程序结束。。。。==");
    }

1.1.3异常的基本处理

【1】抛出异常(throws)

在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理

public static void show2() throws Exception

【2】捕获异常(try...catch)

    try {
            // 监视代码,出现异常,会被catch拦截住这个异常
            show2();
        } catch (Exception e) {
            e.printStackTrace(); // 打印这个异常信息
        }

1.1.4异常的作用

【1】异常是用来定位程序bug的关键信息

【2】可以作为方法内部的一种特殊返回值。以便通知上层调用者,方法的执行问题

1.2自定义异常

1.2.1为什么自定义异常

Java无法为这个世界上全部的问题都提供异常类来代表, 如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了。

1.2.2两种自定义异常

【1】自定义运行时异常

定义一个异常类继承RuntimeException. 重写构造器。 通过throw new 异常类(xxx)来创建异常对象并抛出。

public ItheimaAgeIllegalRuntimeException(String message) {
        super(message);
    }
throw new ItheimaAgeIllegalRuntimeException("年龄非法 age 不能低于1岁不能高于200岁");

【2】自定义编译时异常

定义一个异常类继承Exception. 重写构造器。 通过throw new 异常类(xxx) 创建异常对象并抛出。

public ItheimaAgeIllegalException(String message) {
        super(message);
    }
throw new ItheimaAgeIllegalException("年龄非法 age 不能低于1岁不能高于200岁");

1.3最常见的异常处理方案 

底层的异常抛出去给最外层,最外层集中捕获处理。

2.泛型

2.1认识泛型

2.1.1什么是泛型

定义类、接口、方法时,同时声明了一个或者多个类型变量(如:<E>)。称为泛型类、泛型接口,泛型方法、它们统称为泛型。

2.1.2泛型的作用

泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。

2.1.3泛型的本质

把具体的数据类型作为参数传给类型变量。

2.2泛型类

2.2.1格式

修饰符 class 类名<类型变量,类型变量,…> { }

public class ArrayList<E>{
    . . .
}

2.3泛型接口

2.3.1格式

 修饰符 interface 接口名<类型变量,类型变量,…> { }

public interface A<E>{
    . . .
}

2.4泛型方法、通配符、上下限

2.4.1泛型方法

修饰符 <类型变量,类型变量,…>  返回值类型 方法名(形参列表) {  }

public static <T> void test(T t){    
}

2.4.2通配符

就是 “?” ,可以在“使用泛型”的时候代表一切类型;  E T K V 是在定义泛型的时候使用。

2.4.3上下限

【1】泛型上限:    ? extends Car: ? 能接收的必须是Car或者其子类 。

【2】泛型下限:  ? super Car : ?  能接收的必须是Car或者其父类。

2.5泛型支持的类型

2.5.1特点

泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。

2.5.2包装类

【1】包装类就是把基本类型的数据包装成对象的类型。

基本数据类型对应的包装类(引用数据类型)
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
booleanBoolean

【2】基本类型的数据包装成对象的方案

public static Integer valueOf(int i) 

// 把基本数据类型变成包装类对象。
        // 手工包装:
        // Integer i = new Integer(100); // 过时
        Integer it1 = Integer.valueOf(100);  // 推荐的
        Integer it2 = Integer.valueOf(100);  // 推荐的
        System.out.println(it1 == it2);

【3】自动装箱

基本数据类型可以自动转换为包装类型。

// 自动装箱成对象:基本数据类型的数据可以直接变成包装对象的数据,不需要额外做任何事情
        Integer it11 = 130;
        Integer it22 = 130;
        System.out.println(it11 == it22);

 

【4】自动拆箱

包装类型可以自动转换为基本数据类型。

// 自动拆箱:把包装类型的对象直接给基本类型的数据
        int i = it11;
        System.out.println(i);

 

2.5.3包装类其他的功能

【1】可以把基本类型的数据转换成字符串类型。

// 包装类新增的功能:
        // 1、把基本类型的数据转换成字符串。
        int j = 23;
        String rs1 = Integer.toString(j);   // "23"
        System.out.println(rs1 + 1); // 231

        Integer i2 = j;
        String rs2 = i2.toString(); // "23"
        System.out.println(rs2 + 1 ); // 231

        String rs3 = j + "";
        System.out.println(rs3 + 1 ); // 231

 

【2】可以把字符串类型的数值转换成数值本身对应的真实数据类型。

        // 2、把字符串数值转换成对应的基本数据类型(很有用)。
        String str = "98";
        // int i1 = Integer.parseInt(str);
        int i1 = Integer.valueOf(str);
        System.out.println(i1 + 2);

        String str2 = "98.8";
//        double d = Double.parseDouble(str2);
        double d = Double.valueOf(str2);
        System.out.println(d + 2);

 

3.集合框架

3.1认识集合

3.1.1什么是集合

集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用。

3.1.2集合体系结构

【1】Collection代表单列集合,每个元素(数据)只包含一个值。

【2】Map代表双列集合,每个元素包含两个值(键值对)。

3.1.3Collection集合特点

【1】List系列集合:添加的元素是有序、可重复、有索引

【2】Set系列集合:添加的元素是无序、不重复、无索引

3.2Collection的功能

3.2.1常用方法

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()把集合中的元素,存储到数组中

public static void main(String[] args) {
        // 目标:搞清楚Collection提供的通用集合功能。
        Collection<String> list = new ArrayList<>();

        // 添加元素
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list); // [张三, 李四, 王五]

        // 获取集合的元素个数
        System.out.println(list.size());

        // 删除集合元素
        list.remove("李四");
        System.out.println(list);

        // 判断集合是否为空
        System.out.println(list.isEmpty()); // false

        // 清空集合
        // list.clear();
        // System.out.println(list);

        // 判断集合中是否存在某个数据
        System.out.println(list.contains("张三"));

        // 把集合转换成数组
        Object[] arr = list.toArray();
        System.out.println(Arrays.toString(arr));

        // 把集合转换成字符串数组(拓展)
        String[] arr2 = list.toArray(String[]::new);
    }

3.2.2三种遍历方式

【1】迭代器遍历

(1)迭代器是什么

        迭代器是用来遍历集合的专用方式(数组没有迭代器),在Java中迭代器的代表是Iterator。

(2)通过迭代器获取集合的元素,如果取元素越界会出现什么异常?

        会出现NoSuchElementException异常。

    public static void main(String[] args) {
        // 目标:掌握Collection的遍历方式一:迭代器遍历
        Collection<String> names = new ArrayList<>();
        names.add("张无忌");
        names.add("玄冥二老");
        names.add("宋青书");
//        names.add("殷素素");
        System.out.println(names); // [张无忌, 玄冥二老, 宋青书]
        //                                                      it

        // 1、得到这个集合的迭代器对象
        Iterator<String> it = names.iterator();
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next()); // NoSuchElementException

        // 2、使用一个while循环来遍历
        while (it.hasNext()) {
            String name = it.next();
            System.out.println(name);
        }
    }

【2】增强for循环

增强for可以用来遍历集合或者数组。本质就是迭代器遍历集合的简化写法。

    public static void main(String[] args) {
        // 目标:掌握Collection的遍历方式二:增强for
        Collection<String> names = new ArrayList<>();
        names.add("张无忌");
        names.add("玄冥二老");
        names.add("宋青书");
        names.add("殷素素");

        for (String name : names) {
            System.out.println(name);
        }

        String[] users = {"张无忌", "玄冥二老", "宋青书", "殷素素"};

        for (String user : users) {
            System.out.println(user);
        }
    }

【3】Lambda表达式

    public static void main(String[] args) {
        // 目标:掌握Collection的遍历方式三:lambda
        Collection<String> names = new ArrayList<>();
        names.add("张无忌");
        names.add("玄冥二老");
        names.add("宋青书");
        names.add("殷素素");


//        names.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });

//        names.forEach(s -> System.out.println(s));

        names.forEach(System.out::println);
    }

3.2.3三种遍历方式的区别

【1】如果集合支持索引,可以使用for循环遍历,每删除数据后做i--;或者可以倒着遍历

        // 需求1:删除全部枸杞
        for (int i = 0; i < list2.size(); i++) {
            String name = list2.get(i);
            if(name.contains("枸杞")){
                list2.remove(name);
                i--; // 解决方案1:删除数据后做一步i--操作 (前提是支持索引)
            }
        }
    for (int i = list3.size() - 1; i >= 0; i--) {
            String name = list3.get(i);
            if(name.contains("枸杞")){
                list3.remove(name);
            }
        }

【2】可以使用迭代器遍历,并用迭代器提供的删除方法删除数据。

        // 需求1:删除全部枸杞
        // 方案一:迭代器遍历并删除默认也存在并发修改异常问题。
        // 可以解决3:使用迭代器自己的方法来删除
        Iterator<String> it = list4.iterator();
        while(it.hasNext()){
            String name = it.next();
            if(name.contains("枸杞")){
                it.remove();   // 可以解决3:使用迭代器自己的方法来删除当前数据
            }
        }
        System.out.println(list4);

【3】增强for循环/Lambda遍历均不能解决并发修改异常问题,因此增它们只适合做数据的遍历,不适合同时做增删操作。

3.3List集合

3.3.1List系列集合特点

有序,可重复,有索引

3.3.2List集合的特有方法

List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。

方法名称说明
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素
    public static void main(String[] args) {
        // 目标:掌握List系列集合独有的功能。
        ArrayList<String> names = new ArrayList<>(); // 一行经典代码

        // 添加数据
        names.add("张三");
        names.add("李四");
        names.add("王五");
        names.add("赵六");
        System.out.println(names); // [张三, 李四, 王五, 赵六]

        // 给第三个位置插入一个数据:赵敏
        names.add(2, "赵敏");
        System.out.println(names);

        // 删除李四
        System.out.println(names.remove(1)); // 根据下标删除,返回删除的数据
        System.out.println(names);

        // 把王五修改成:金毛
        System.out.println(names.set(2, "金毛")); // 根据下标修改,返回修改前的数据
        System.out.println(names);

        // 获取张三
        System.out.println(names.get(0));
    }

 

3.3.3List集合支持的遍历方式

【1】for循环

【2】迭代器

【3】增强for循环

【4】Lambda表达式

    public static void main(String[] args) {
        // 1、for循环
        for (int i = 0; i < names.size(); i++) {
            System.out.println(names.get(i));
        }

        // 2、迭代器
        Iterator<String> it = names.iterator();
        while (it.hasNext()) {
            String name = it.next();
            System.out.println(name);
        }

        // 3、增强for
        for (String name : names) {
            System.out.println(name);
        }

        // 4、lambda表达式
        names.forEach(name ->  System.out.println(name) );


        System.out.println(15 >> 1);
    }

3.4ArrayList

ArrayList底层是基于数组存储数据的。

3.4.1特点

【1】有序,可重复,有索引。

【2】查询速度快(注意:是根据索引查询数据快),查询数据通过地址值和索引定位,查询任意数据耗时相同。

【3】增删数据效率低,可能需要把后面很多的数据进行前移。

3.5LinkedList

LinkedList底层是基于链表存储数据的。

3.5.1特点

【1】有序,可重复,有索引。

【2】链表中的数据是一个一个独立的结点组成的,结点在内存中是不连续的,每个结点包含数据值和下一个结点的地址

【3】查询慢,无论查询哪个数据都要从头开始找。

【4】链表增删相对快。对首尾元素进行增删改查的速度是极快的。

3.5.2 LinkedList的特有方法

很多首尾操作的特有方法。

方法名称说明
public void addFirst​(E e)在该列表开头插入指定的元素
public void addLast​(E e)将指定的元素追加到此列表的末尾
public E getFirst​()返回此列表中的第一个元素
public E getLast​()返回此列表中的最后一个元素
public E removeFirst​()从此列表中删除并返回第一个元素
public E removeLast​()从此列表中删除并返回最后一个元素

3.5.3应用场景 

【1】设计队列

队列的特点:先进先出,后进后出

        //排队问题
        LinkedList<String> list=new LinkedList<>();
        list.addLast("西门吹雪");
        list.addLast("赵敏");
        list.addLast("金毛狮王");
        list.addLast("陆小凤");
        System.out.println(list);

        list.removeFirst();
        list.removeFirst();
        System.out.println(list);

【2】设计栈

栈的特点:先进后出,后金先出

数据进入栈模型的过程称为:进栈(push) 

数据离开栈模型的过程称为:出栈(pop) 

        //栈
        LinkedList<String> list1=new LinkedList<>();
        //压栈
        list1.push("第一颗子弹");
        list1.push("第二颗子弹");
        list1.push("第三颗子弹");
        list1.push("第四颗子弹");
        System.out.println(list1);

        //出栈
        list1.pop();
        list1.pop();
        System.out.println(list1);

 

  • 37
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值