day20-集合(Collection、 迭代器、List、ArrayList、LinkedList)

本文详细介绍了Java中Collection接口及其子接口(如Set和List)的概念、区别,以及如何使用它们。重点讲解了ArrayList和LinkedList的实现、特性和源码分析,同时涵盖了迭代器的使用和数据结构中的栈与队列概念。
摘要由CSDN通过智能技术生成

1.Collection集合

1.1数组和集合的区别【理解】

  • 相同点

    都是容器,可以存储多个数据

  • 不同点

    • 数组的长度是不可变的,集合的长度是可变的

    • 数组可以存基本数据类型和引用数据类型

      集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类

1.2集合类体系结构【理解】

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

1.3Collection 集合概述和使用【应用】

  • Collection集合概述

    • 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
    • JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现
  • 创建Collection集合的对象

    • 多态的方式
    • 具体的实现类ArrayList
  • Collection集合常用方法
    在这里插入图片描述boolean addAll(Collection<? extends E> c)代表一次添加多个元素,参数就是集合

    public class Main {
        public static void main(String[] args) {
            //目的: 为了学习Collection接口里面的方法
            //自己在做一些练习的时候,还是按照之前的方式去创建对象。
            Collection<Integer> coll = new ArrayList<>();
    
            //1.添加元素
            //细节1: 如果我们要往List系列集合中添加数据,那么方法永远返回true,因为List系列的是允许元素重复的
            //细节2:如果我们要往Set系列集合中添加数据,如果当前要添加元素不存在,方法返回true,表示添加成功。
            //如果当前要添加的元素已经存在,方法返回false,表示添加失败。
            //因为Set系列的集合不允许重复。
            coll.add(1);
            coll.add(2);
            coll.add(3);
            System.out.println(coll);//[1, 2,3]
    
            //2.删除元素
            //细节1:因为Collection里面定义的是共性的方法,所以此时不能通过索引进行删除。只能通过元素的对象进行删除
            //细节2: 方法会有一个布尔类型的返回值,删除成功返回true,删除失败返回false
            //如果要删除的元素不存在,就会删除失败。
            System.out.println(coll.remove(2));
            System.out.println(coll);//true
            System.out.println(coll.remove(10));
            System.out.println(coll);//false
    
            //3.判断元素是否包含
            //细节: 底层是依赖equals方法进行判断是否存在的。
            //所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在javabean类中,一定要重写equals方法.
            System.out.println(coll.contains(1));//true
            System.out.println(coll.contains(10));//false
    
            //4.判断集合是否为空
            System.out.println(coll.isEmpty());//false
    
            //6.获取集合长度
            System.out.println(coll);//[1, 3]
            System.out.println(coll.size());//2]
    
            //7.清空集合
            coll.clear();
            System.out.println(coll);//[]
        }
    }
    

1.4Collection集合的遍历

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

1.4.1 迭代器遍历
  • 迭代器介绍

    • 迭代器,集合的专用遍历方式
    • Iterator iterator(): 返回此集合中元素的迭代器,通过集合对象的iterator()方法得到
  • Iterator中的常用方法

    ​ boolean hasNext(): 判断当前位置是否有元素可以被取出
    ​ E next(): 获取当前位置的元素,将迭代器对象移向下一个索引位置

  • Collection集合的遍历

      public class Main {
          public static void main(String[] args) {
              Collection<Integer> coll = new ArrayList<>();
              coll.add(1);
              coll.add(2);
              coll.add(3);
              coll.add(4);
              coll.add(5);
              coll.add(6);
      
              //获取迭代器对象
              Iterator<Integer> iterator = coll.iterator();
              //循环遍历
              while (iterator.hasNext()){
                  int num = iterator.next();
                  System.out.println(num);
              }
      
          }
      }
    

注意事项

在这里插入图片描述

  • 报错NoSuchElementException在这里插入图片描述
  • 迭代器遍历完毕,指针不会复位如果要遍历第二次,则需要重新获取迭代器对象
    在这里插入图片描述
  • 循环中只能用一次next方法,使用多次后,会出现跳跃取值和越界
    在这里插入图片描述在这里插入图片描述
  • 迭代器遍历时,不能用集合的方法进行增加或者删除
    在这里插入图片描述

如果实在要删除,就要通过迭代器中的remove方法删除,如果要添加,暂时没有办法

  • 迭代器中删除的方法

    ​ void remove(): 删除迭代器对象当前指向的元素

    public class IteratorDemo2 {
        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("b");
            list.add("c");
            list.add("d");
    
            Iterator<String> it = list.iterator();
            while(it.hasNext()){
                String s = it.next();
                if("b".equals(s)){
                    //指向谁,那么此时就删除谁.
                    it.remove();
                }
            }
            System.out.println(list);
        }
    }
    

在这里插入图片描述

1.4.2 增强for

在这里插入图片描述

  • 代码

    public class MyCollectonDemo1 {
        public static void main(String[] args) {
            ArrayList<String> list =  new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("c");
            list.add("d");
            list.add("e");
            list.add("f");
    
            //1,数据类型一定是集合或者数组中元素的类型
            //2,str仅仅是一个变量名而已,在循环的过程中,依次表示集合或者数组中的每一个元素
            //3,list就是要遍历的集合或者数组
            for(String str : list){
                System.out.println(str);
            }
        }
    }
    

在这里插入图片描述

1.4.3 lambda表达式

​ 利用forEach方法,再结合lambda表达式的方式进行遍历

public class A07_CollectionDemo7 {
    public static void main(String[] args) {
       /* 
        lambda表达式遍历:
                default void forEach(Consumer<? super T> action):
        */

        //1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("zhangsan");
        coll.add("lisi");
        coll.add("wangwu");
        //2.利用匿名内部类的形式
        //底层原理:
        //其实也会自己遍历集合,依次得到每一个元素
        //把得到的每一个元素,传递给下面的accept方法
        //s依次表示集合中的每一个数据
       /* coll.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        //lambda表达式
        coll.forEach(s -> System.out.println(s));
    }
}

在这里插入图片描述

2.List集合

2.1List集合的概述和特点【记忆】

  • List集合的概述
    • 有序集合,这里的有序指的是存取顺序
    • 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
    • 与Set集合不同,列表通常允许重复的元素
  • List集合的特点
    • 存取有序
    • 可以重复
    • 有索引

2.2List集合的特有方法【应用】

  • 方法介绍

在这里插入图片描述

  • 示例代码
public class Main {
    public static void main(String[] args) {
        //List系列集合中的两个删除的方法
        //1.直接删除元素
        //2.通过索引进行删除

        //1.创建集合并添加元素
        List<Integer> list = new ArrayList<>();

        list.add(1);
        list.add(2);
        list.add(3);

        //2.删除元素
        //请问:此时删除的是1这个元素,还是1索引上的元素?
        list.remove(1);
        System.out.println(list);//[1, 3]
        //为什么?
        //因为在调用方法的时候,如果方法出现了重载现象
        //优先调用,实参跟形参类型一致的那个方法。

        //如果非要删除指定元素,则需要把int改为Integer类型
        //手动装箱,手动把基本数据类型的1,变成Integer类型
        Integer i = Integer.valueOf(1);
        list.remove(i);
        System.out.println(list);//[3]

        //3.修改元素
        int result = list.set(0,123);
        System.out.println(list);//[123]
        System.out.println(result);//3

        //4.get方法,通过索引
        System.out.println(list.get(0));//123
    }
}

2.3List集合的五种遍历方式【应用】

  1. 迭代器
  2. 列表迭代器
  3. 增强for
  4. Lambda表达式
  5. 普通for循环

代码示例:

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        //1.迭代器
        Iterator<Integer> it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

        //2.列表迭代器
        ListIterator<Integer> ilt = list.listIterator();
        while (ilt.hasNext()){
            System.out.println(ilt.next());
        }

        //列表迭代器可以在遍历过程中添加和删除方法
        System.out.println(list);//[1, 2, 3, 4]
        ListIterator<Integer> ilt1 = list.listIterator();
        while (ilt1.hasNext()){
            if(ilt1.next()==3){
                ilt1.add(33);
            }
            if(ilt1.next()==4){
                ilt1.remove();
            }
        }
        System.out.println(list);//[1, 2, 3, 33]


        //3.增强for
        for (Integer i : list) {
            System.out.println(i);
        }

        //4.Lambda表达式
        list.forEach(new Consumer<Integer>(){
            @Override
            public void accept(Integer i){
                System.out.println(i);
            }
        });

        list.forEach(i-> System.out.println(i));

        //5.普通for循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }

列表迭代器细节

右边两个方法不常用,相当于往前移动,不常用的原因是因为,迭代器初始指向了第一个元素,而不是最后一个元素。
在这里插入图片描述
在这里插入图片描述

3.数据结构

3.1数据结构之栈和队列【记忆】

  • 栈结构

    ​ 先进后出

  • 队列结构

    ​ 先进先出

3.2数据结构之数组和链表【记忆】

  • 数组结构

    在这里插入图片描述

  • 链表结构

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

4.List集合的实现类

4.1List集合子类的特点【记忆】

  • ArrayList集合

    ​ 底层是数组结构实现,查询快、增删慢

  • LinkedList集合

    ​ 底层是链表结构实现,查询慢、增删快
    在这里插入图片描述

4.2LinkedList集合的特有功能【应用】

  • 特有方法
    在这里插入图片描述

  • 示例代码

    LinkedList<Integer> list = new LinkedList<Integer>();
    LinkedList<Integer> list1 = new LinkedList<Integer>();
    
    //1.在开头插入指定元素
    list.addFirst(1);
    list.addFirst(2);
    list.addFirst(3);
    System.out.println(list);//[3, 2, 1]
    //list.addFirst(num)等价于list.add(0,num);
    list1.add(0,1);
    list1.add(0,2);
    list1.add(0,3);
    System.out.println(list1);//[3, 2, 1]
    
    //2.在末尾插入指定元素
    list.addLast(4);
    System.out.println(list);//[3, 2, 1, 4]
    //list.addLast(num)等价于list.add(list.size(),num);
    list1.add(list1.size(),4);
    System.out.println(list1);//[3, 2, 1, 4]
    
    //3.获取列表中第一个元素
    System.out.println(list.getFirst());//3
    //list.getFirst()等价于list.get(0)
    System.out.println(list1.get(0));//3
    
    //4.获取列表中最后一个元素
    System.out.println(list.getLast());//4
    //list.getFirst()等价于list.get(list.size()-1)
    System.out.println(list.get(list.size()-1));//4
    
    //5.从此列表中删除并返回第一个元素
    System.out.println(list.removeFirst());//3
    System.out.println(list);//[2, 1, 4]
    //list.removeFirst()等价于list.remove(0)
    System.out.println(list1.remove(0));//3
    System.out.println(list1);//[2, 1, 4]
    
    //6.从此列表中删除并返回最后一个元素
    System.out.println(list.removeLast());//4
    System.out.println(list);//[2, 1]
    //list.removeLast()等价于list.remove(list.size()-1)
    System.out.println(list1.remove(list1.size()-1));//4
    System.out.println(list1);//[2, 1]
    

5. 源码分析

5.1 ArrayList源码分析:

核心步骤:

  1. 创建ArrayList对象的时候,他在底层先创建了一个长度为0的数组。

    数组名字:elementDate,定义变量size。

    size这个变量有两层含义:
    ①:元素的个数,也就是集合的长度
    ②:下一个元素的存入位置

  2. 添加元素,添加完毕后,size++
    在这里插入图片描述

扩容时机一:

  1. 当存满时候,会创建一个新的数组,新数组的长度,是原来的1.5倍,也就是长度为15.再把所有的元素,全拷贝到新数组中。如果继续添加数据,这个长度为15的数组也满了,那么下次还会继续扩容,还是1.5倍。

    在这里插入图片描述

扩容时机二:

  1. 一次性添加多个数据,扩容1.5倍不够,怎么办呀?

    如果一次添加多个元素,1.5倍放不下,那么新创建数组的长度以实际为准。

举个例子:
在一开始,如果默认的长度为10的数组已经装满了,在装满的情况下,我一次性要添加100个数据很显然,10扩容1.5倍,变成15,还是不够,

怎么办?

此时新数组的长度,就以实际情况为准,就是110

源码分析

  • 第一次添加数据:
    在这里插入图片描述
  • 添加第11个元素:
    在这里插入图片描述

5.2 LinkedList源码分析:

底层是双向链表结构

核心步骤如下:

  1. 刚开始创建的时候,底层创建了两个变量:一个记录头结点first,一个记录尾结点last,默认为null
  2. 添加第一个元素时,底层创建一个结点对象,first和last都记录这个结点的地址值
  3. 添加第二个元素时,底层创建一个结点对象,第一个结点会记录第二个结点的地址值,last会记录新结点的地址值

具体分析过程可以参见视频讲解。

在这里插入图片描述

5.3 迭代器源码分析:

迭代器遍历相关的三个方法:

  • Iterator iterator() :获取一个迭代器对象

  • boolean hasNext() :判断当前指向的位置是否有元素

  • E next() :获取当前指向的元素并移动指针

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值