• day14_集合


    今日内容

    零、 复习昨日
    一、集合框架体系
    二、Collection
    三、泛型
    四、迭代
    五、List(ArrayList、LinkedList)

    零、 复习

    throw和throws什么区别

    throwthrows
    位置方法里面方法签名上
    怎么写throw + 异常对象throws+异常类名(多个)
    作用真正抛出异常对象声明抛出的异常类型

    运行时异常有哪些,什么特点

    • 运行时异常,查异常类是否继承自RuntimeException
    • 特点: 不用主动处理
    • 别称: 不受检查异常

    编译期异常有哪些,什么特点

    • 只要不是RuntimeException及其子类,那都是编译期
    • 特点: 必须处理
    • 别称: 受检查异常(CheckedException)

    异常的处理方式哪些,什么区别

    • 抛出,代码停止
    • 捕获,代码继续

    finally干什么的

    • 放在最后执行,其中写的释放资源的代码

    一、集合框架体系

    数组: 是一个容器,用来存放数据的

    • 定长
    • 只能存储同一种数据类型的数据
    • int[] 可以存储int值,Student[] 可以存储引用类型
    • 只有一个length属性,没有方法,使用时功能简单

    集合: 是一个容器,用来存放数据的

    • 不定长
    • 存各种各样类型
    • 只能存储引用类型
    • 提供了操作数据的各种方法

    集合体系

    image-20230731093616057

    今天主要学习Collection,List,ArrayList,LinkedList…

    二、Collection

    Collection是单列集合层次结构中的根接口
    一些 集合允许有重复的元素,而另一些则不允许。一些 集合是有序的,而另一些则是无序的
    Collection下面的一些子实现类有些有重复元素,有些没有,有些可以有序,有些无序

    方法: 每个都很常见,很重要

    ps: Collection是接口,不能创建对象,为了演示这些API,需要使用子实现类,使用最常用的ArrayList集合来实现方法

        public static void main(String[] args) {
            // Collection是接口,不能直接创建对象
            // 但是当做父引用指向子类对象
            Collection col = new ArrayList(); // 向上转型
    
            // 存放元素 add(Object o)
            col.add(1);// 1--> 自动装箱Integer对象 --> Object
            col.add("a");
            col.add(new Date( ));
            System.out.println(col );
    
            // 再创建集合
            Collection col2 = new ArrayList();
            col2.add(11);
            col2.add(22);
            col2.add(33);
    
            // 批量添加 addAll(Collection c)
            col.addAll(col2);// 将参数与集合中的所有数据都添加到当前集合
    
            System.out.println(col );
    
            // 移除元素
            // boolean remove(Object o) 删除指定元素
            boolean r1= col.remove(-11);
            System.out.println("删除是否成功:" + r1 );
            System.out.println("删除后: "+col );
    
            // boolean removeAll(Collection c)
            // 批量删除
            // col.removeAll(col2);// 删除指定数据
            // System.out.println("批量删除后: " + col );
    
            // 保留全部(反向删除)
            // boolean retainAll(Collection c)
            col.retainAll(col2);// 保留指定数据,删除其他数据
            System.out.println("保留全部"+col );
    
            // 删除全部数据(清空)
            // col.clear();
            // System.out.println("清空: "+col );
    
            // 获得集合大小(尺寸/容量)
            int size = col.size( );
            System.out.println(size );
    
            // 判断集合是否为空(没有元素,长度为0即为空)
            boolean empty = col.isEmpty( );
            System.out.println(empty );
    
            // 判断集合是否包含指定元素
            // contains
            boolean contains = col.contains(11);
            System.out.println("是否包含:" + contains );
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    三、迭代[重要]

    迭代 (遍历), 将集合元素迭代,目的是取出元素.

        public static void main(String[] args) {
    
            Collection col = new ArrayList(  );
            col.add(1);
            col.add(2);
            col.add(3);
            col.add(4);
            col.add(5);
            col.add(6);
    
            // 遍历(迭代)集合
            // 1) 获得迭代器
            Iterator iterator = col.iterator( );
            // 2) 通过迭代器完成迭代(遍历)
            while(iterator.hasNext()){// hasNext() 判断有无下一个
                Object o = iterator.next( );// next()取出下一个元素
                System.out.println(o );
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    image-20230419105956171

    增强for循环(foreach)

      public static void main(String[] args) {
    
            Collection col = new ArrayList(  );
            col.add(1);
            col.add(2);
            col.add(3);
            col.add(4);
            col.add(5);
            col.add(6);
    
            // 遍历(迭代)集合
            // 1) 获得迭代器
            Iterator iterator = col.iterator( );
            // 2) 通过迭代器完成迭代(遍历)
            while(iterator.hasNext()){// hasNext() 判断有无下一个
                Object o = iterator.next( );// next()取出下一个元素
                System.out.println(o );
            }
            // 使用增强for循环,改写迭代器遍历
            /**
             * for(数据类型 变量:集合/数组){
             *
             * }
             * 1) 冒号右边是写要被遍历的集合或者数组对象
             * 2) 每次从集合或者数组取出的值赋值给左边变量
             */
            System.out.println("-------" );
            for (Object o : col){
                System.out.println(o );
            }
    
            System.out.println("----------" );
            int[] arr = {11,22,33,44};
            for (int i : arr){
                System.out.println(i );
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    四、泛型

    泛型在集合中主要是用来规定数据类型的.

    语法: 设计时 <类型> , 例如 ,
    ps: E,K,V,T这些都是见名知意的简写,其实是可以随意写的

    ​ 使用时(创建类对象)指定泛型,即指定明确的数据类型

    作用:

    • 约束集合存储的数据类型
    • 避免数据类型转换
       public static void main(String[] args) {
    
            // 没有泛型
            Collection col = new ArrayList();
            // 类型没有限制
            col.add(1);
            col.add("2");
            col.add(1.1);
    
            // for (Object o : col){
            //     String s = (String) o;
            // }
    
    
            // 使用泛型
            Collection<String> col2 = new ArrayList<>();
            // 就可以限制数据类型
            col2.add("A");
            col2.add("B");
            for (String s : col2){
                System.out.println(s );
            }
    
            // 使用泛型
            Collection<Integer> col3 = new ArrayList<>();
            col3.add(1);
            col3.add(2);
            col3.add(3);
            for (Integer i : col3){
                System.out.println(i );
            }
            /**
             * 为什么要用泛型?
             * 1) 经验: 虽然集合可以存储多种数据类型,但是大部分场景都是只存同一种数据
             * 2) 最主要的原因是: 没有泛型,类型太杂,需要使用指定类型还需要强制
             *    但是强制还容易报错
             *    所以:泛型的好处就会可以约定数据类型,从而减少数据类型转型
             */
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    泛型: 可以研究泛型类,泛型参数,泛型方法等等…

    五、List

    • List是Collection的子接口
    • List是有序集合: 有序是指集合迭代顺序和插入顺序一致
    • List集合允许重复元素!!
    • List集合提供了可以针对索引(下标)操作元素的方法

    List接口中的方法大部分与父接口Collection中一致,
    但是除此之外的方法,确实提了可以通过下标操作元素(CRUD)的方法

    • void add(int index,E e) 按照下标位置加入元素 (增)(Create创建/新增)
    • E remove(int index) 按照下标位置移除元素 (删)(Delete删除)
    • E set(int index,E e) 按照下标位置设置(修改)元素 (改)(Update更新/修改)
    • E get(int index) 按照下标位置获得元素 (查)(Read读取/查询)

    List是接口,没有办法演示其中的方法

    List接口有两个常用的实现类:ArrayListLinkedList

    5.1 ArrayList[重点]

    ArrayList实现了List接口,即ArrayList也是有序集合,也允许重复元素,且那些关于下标操作集合的方法ArrayList都有!

    ArrayList不保证线程安全

    ArrayList底层是数组,大小可变是指它会扩容(不是真正大小可变)

    5.1.1 演示方法

    构造方法

    • ArrayList() 创建空集合,默认创建了一个长度为10的数组
    • ArrayList(Collection c) 创建一个集合,集合内直接就有指定的参数
    • ArrayList(int initialCapacity) 创建一个指定初始化容量的数组
     ArrayList<Integer> list = new ArrayList<>( );
    
    • 1

    方法

    • 其他的方法上午在Collection中已经学过
    • void add(int index,E e)
    • E remove(int index)
    • E get(int index)
    • E set(int index,E e)
        public static void main(String[] args) {
            // 定义泛型
            // 空参构造,创建空集合(默认容量10)
            ArrayList<Integer> list = new ArrayList<>( );
            // 最基本的添加方法
            list.add(3);
            list.add(1);
            list.add(1);
            list.add(4);
            list.add(4);
            list.add(2);
            // 遍历(保证顺序-->有序)
            // 允许重复元素
            for (Integer i : list) {
                System.out.println(i );
            }
    
            // 其他常规方法不再演示
            // 主要掌握关于下标的方法
            // 311442
            // 按照下标插入 add(int i,E e)
            list.add(3,0);
            System.out.println(list );
    
            // 按照下标获得元素(取值) E get(int i)
            Integer e = list.get(4);
            System.out.println("下标4的值: " + e );
    
            // 按照下标修改值 E set(int i,E e)
            Integer old = list.set(4, 10);
            System.out.println("修改后的集合:" + list );
            System.out.println("返回的数据:" + old );
    
            // 按照下标删除 E remove(int i)
            Integer remove = list.remove(4);
            System.out.println("删除下标3的数据后:" + list );
            System.out.println("返回的数据:" + remove );
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    5.1.2 底层原理[掌握|理解]

    ArrayList底层是使用数组,默认长度是10,但是存储元素多于10时会扩容.

    如何扩容的?

    • 当加入元素时,先判断加入后会不会超出默认长度
    • 如果没有超出默认长度
      • add(Object o) 元素直接放最后
      • add(int index,Object o) 先将该位置以后的元素依次往后移动一个,然后再将该元素放入该位置
    • 当加入元素时,判断加入后长度会不会超出容量,如果超出就要扩容
    • 扩容是创建一个新的数组,容量是原来的1.5倍
    • 将原来数组的元素依次拷贝到新数组
    • 然后再放入新元素
    // jdk源码   
     private void grow(int minCapacity) {
            // 
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);// 1.5倍
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    /*
    给定的代码是一个名为"grow"的方法,用于增加数组的容量。它接受一个参数"minCapacity",表示数组应该具有的最小容量。
    以下是代码的逐步解释:
    1. 方法首先使用"elementData"数组的"length"属性获取当前容量。
    2. 然后通过将旧容量的一半加上旧容量本身来计算新容量。这是使用右移运算符(>>)实现的,它将值除以2。
    3. 接下来,它检查新容量减去最小容量是否小于0。如果这个条件为真,说明新容量不足以满足所需的最小容量。在这种情况下,它将新容量设置为等于最小容量。
    4. 然后,它检查新容量减去最大数组大小是否大于0。如果这个条件为真,说明新容量超过了数组允许的最大大小。在这种情况下,它调用"hugeCapacity"方法来计算一个在允许范围内的新容量。
    5. 最后,它使用"Arrays.copyOf"方法创建一个具有更新容量的新数组。"elementData"数组被赋予新数组,从而增加了其容量。
    总之,"grow"方法增加数组的容量以满足最小容量要求,并确保不超过允许的最大大小。
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    5.1.3 特点[记住]

    ArrayList特点: 1) 有序 2) 重复 3) 查询更新效率高 4) 删除插入效率低

    应用场景: 适合那些查询频率高的地方. 且基本大部分场景都是经常查不经常删除和插入的,所以呢ArrayList就非常常用!!! 如果以后没有特殊说明,直接就使用ArrayList!!

  • 相关阅读:
    计算机保研复习
    当你在Linux系统中编译安装MySQL数据库卡住了怎么办?
    【C++】list的使用(上)
    GaussDB拿下的安全认证CC EAL4+究竟有多难?
    七、MySql表的内置函数
    基于QT实现的图形学绘制系统 文档+项目源码及可执行EXE文件+系统使用说明书
    机器人控制算法五之 机器人由空间变换transform建立VRML模型
    软件开发架构与网络编程
    ReactNative 开发之旅: 项目配置与版本管理实践
    【二分法】多种情况下的边界条件,区间选择汇总,小结
  • 原文地址:https://blog.csdn.net/weixin_39641494/article/details/134062325