集合

本文详细介绍了Java中的集合框架,包括集合和Collection接口、不同类型的集合(如ArrayList和LinkedList)、泛型的应用、遍历方式(迭代和增强for循环),以及ArrayList的底层原理和特点。
摘要由CSDN通过智能技术生成

一、集合

1.1 集合介绍

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

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

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

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

1.2 集合划分图示

在这里插入图片描述

二、Collection

2.1 Collection介绍

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

2.2 常用方法

  • 注:Collection是接口,不能创建对象,为了演示这些API,需要使用子实现类,使用最常用的ArrayList集合来实现方法
说明方法签名返回值
添加元素boolean add(E e)布尔值
添加集合进行批量元素boolean addAll(Collection c)布尔值
根据元素删除boolean remove(Object o)布尔值
根据集合进行删除boolean removeAll(Collection c)布尔值
保留指定数据boolean retainAll(Collection c)布尔值
删除全部数据void clear()
集合长度int size()int 整型
判断是否为空boolean isEmpty()布尔值
判断是否包含boolean contains(E e)布尔值
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 );
    }

三、遍历

3.1 迭代

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

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( );// 获取元素,移动指针
            System.out.println(o );
        }
    } 

在这里插入图片描述

3.2 增强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 );
        }
    }

四、泛型

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

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

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

  • 作用:

    • 约束集合存储的数据类型
    • 避免数据类型转换
  • 泛型: 可以研究泛型类,泛型参数,泛型方法等等…

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集合

5.1 List介绍

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

5.2 常用方法

  • List接口中的方法大部分与父接口Collection中一致,
    但是除此之外的方法,确实提了可以通过下标操作元素(CRUD)的方法
  • List是接口,没有办法演示其中的方法
  • List接口有两个常用的实现类:ArrayList和LinkedList
说明方法标签返回值
根据下标位置加入元素void add(int index,E e)
根据下标位置移除元素E remove(int index)返回被删除的元素
根据下标位置进行修改E set(int index,E e)返回被修改的元素
根据下标位置获得元素E get(int index)返回获得的元素

5.3 ArrayList[重点]

  • ArrayList实现了List接口,即ArrayList也是有序集合,也允许重复元素,且那些关于下标操作集合的方法ArrayList都有!
  • ArrayList不保证线程安全
  • ArrayList底层是数组,大小可变是指它会扩容(不是真正大小可变)

5.3.1构造方法

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

5.3.2 常用方法:

  • 其他的方法上午在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 );
    }

5.3.3 底层原理[掌握|理解]【面试】

  • 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"方法增加数组的容量以满足最小容量要求,并确保不超过允许的最大大小。
*/

5.3.4 特点[记住]

  • ArrayList特点: 1) 有序 2) 重复 3) 查询更新效率高 4) 删除插入效率低
  • 应用场景: 适合那些查询频率高的地方. 且基本大部分场景都是经常查不经常删除和插入的,所以呢ArrayList就非常常用!!! 如果以后没有特殊说明,直接就使用ArrayList!!

5.4 LinkedList[熟悉]

  • LinkedList是List的实现类,那么LinkedList也是允许重复,有序
    且LinkedList集合也有关于下标操作集合的方法,但是还提供了一些关于操作开头和结尾的方法
    entData"数组被赋予新数组,从而增加了其容量。
    总之,"grow"方法增加数组的容量以满足最小容量要求,并确保不超过允许的最大大小。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Su sir~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值