day14_集合

今日内容

零、 复习昨日

一、集合框架体系

二、Collection

三、泛型

四、迭代

五、List(ArrayList、LinkedList)

零、 复习

throw和throws什么区别

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

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

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

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

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

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

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

finally干什么的

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

一、集合框架体系

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

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

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

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

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

二、Collection

Collection是单列集合层次结构中的根接口

一些 集合允许有重复的元素,而另一些则不允许。一些 集合是有序的,而另一些则是无序的

Collection下面的一些子实现类有些有重复元素,有些没有,有些可以有序,有些无序
方法: 每个都很常见,很重要

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

java 复制代码
    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 );
    }

三、迭代[重要]

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

java 复制代码
    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循环(foreach)

java 复制代码
  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 );
        }
    }

四、泛型

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

语法: 设计时 <类型> , 例如<E> <K> ,<K,V> <T>

ps: E,K,V,T这些都是见名知意的简写,其实是可以随意写的

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

作用:

  • 约束集合存储的数据类型
  • 避免数据类型转换
java 复制代码
   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) 最主要的原因是: 没有泛型,类型太杂,需要使用指定类型还需要强制
         *    但是强制还容易报错
         *    所以:泛型的好处就会可以约定数据类型,从而减少数据类型转型
         */
    }

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

五、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) 创建一个指定初始化容量的数组
java 复制代码
 ArrayList<Integer> list = new ArrayList<>( );

方法

  • 其他的方法上午在Collection中已经学过
  • void add(int index,E e)
  • E remove(int index)
  • E get(int index)
  • E set(int index,E e)
java 复制代码
    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 );
    }

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

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

  • 当加入元素时,先判断加入后会不会超出默认长度
  • 如果没有超出默认长度
    • add(Object o) 元素直接放最后
    • add(int index,Object o) 先将该位置以后的元素依次往后移动一个,然后再将该元素放入该位置
  • 当加入元素时,判断加入后长度会不会超出容量,如果超出就要扩容
  • 扩容是创建一个新的数组,容量是原来的1.5倍
  • 将原来数组的元素依次拷贝到新数组
  • 然后再放入新元素
java 复制代码
// 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"方法增加数组的容量以满足最小容量要求,并确保不超过允许的最大大小。
*/

5.1.3 特点[记住]

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

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

相关推荐
为将者,自当识天晓地。10 分钟前
c++多线程
java·开发语言
daqinzl18 分钟前
java获取机器ip、mac
java·mac·ip
激流丶34 分钟前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
Themberfue37 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
让学习成为一种生活方式1 小时前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
晨曦_子画1 小时前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
算法与编程之美1 小时前
文件的写入与读取
linux·运维·服务器
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
长弓三石1 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙