黑马Java——集合进阶(List、Set、泛型、树)

news2024/9/22 5:00:14

一、集合的体系结构

1、单列集合(Collection)

 二、Collection集合

1、Collection常见方法

1.1代码实现:

import java.util.ArrayList;
import java.util.Collection;

public class A01_CollectionDemo1 {
    public static void main(String[] args) {
/*
        public boolean add(E e)             添加
        public void clear()                 清空
        public boolean remove(E e)          删除
        public boolean contains(Object obj) 判断是否包含
        public boolean isEmpty()            判断是否为空
        public int size()                   集合长度


       注意点:
        Collection是一个接口,我们不能直接创建他的对象。
        所以,现在我们学习他的方法时,只能创建他实现类的对象。
        实现类:ArrayList
*/
        //目的:为了学习Collection接口里面的方法
        //自己在做一些练习的时候,还是按照之前的方式去创建对象。
        Collection<String> coll = new ArrayList<>();


        //1.添加元素
        //细节1:如果我们要往List系列集合中添加数据,那么方法永远返回true,因为List系列的是允许元素重复的。
        //细节2:如果我们要往Set系列集合中添加数据,如果当前要添加元素不存在,方法返回true,表示添加成功。
        //                                       如果当前要添加的元素已经存在,方法返回false,表示添加失败。
        //                                       因为Set系列的集合不允许重复。
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        System.out.println(coll);

        //2.清空
        //coll.clear();

        //3.删除
        //细节1:因为Collection里面定义的是共性的方法,所以此时不能通过索引进行删除。只能通过元素的对象进行删除。
        //细节2:方法会有一个布尔类型的返回值,删除成功返回true,删除失败返回false
        //如果要删除的元素不存在,就会删除失败。
        System.out.println(coll.remove("aaa"));
        System.out.println(coll);


        //4.判断元素是否包含
        //细节:底层是依赖equals方法进行判断是否存在的。
        //所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在javabean类中,一定要重写equals方法。
        boolean result1 = coll.contains("bbb");
        System.out.println(result1);



        //5.判断集合是否为空
        boolean result2 = coll.isEmpty();
        System.out.println(result2);//false


        //6.获取集合的长度
        coll.add("ddd");
        int size = coll.size();
        System.out.println(size);//3

    }
}

1.2 contains方法重写equals方法示例:(idea可自动重写)

import java.util.ArrayList;
import java.util.Collection;

public class A02_CollectionDemo2 {
    public static void main(String[] args) {
        //1.创建集合的对象
        Collection<Student> coll = new ArrayList<>();


        //2.创建三个学生对象
        Student s1 = new Student("zhangsan",23);
        Student s2 = new Student("lisi",24);
        Student s3 = new Student("wangwu",25);


        //3.把学生对象添加到集合当中
        coll.add(s1);
        coll.add(s2);
        coll.add(s3);

        //4.判断集合中某一个学生对象是否包含
        Student s4 = new Student("zhangsan",23);
        //因为contains方法在底层依赖equals方法判断对象是否一致的。
        //如果存的是自定义对象,没有重写equals方法,那么默认使用Object类中的equals方法进行判断,而Object类中equals方法,依赖地址值进行判断。
        //需求:如果同姓名和同年龄,就认为是同一个学生。
        //所以,需要在自定义的Javabean类中,重写equals方法就可以了。
        System.out.println(coll.contains(s4));
    }
}

重写

 @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

2、Collection的遍历方式(3种)

Collection的遍历的三种方式:

  • 迭代器遍历
  • 增强for循环
  • Lambda表达式

2.1迭代器遍历

迭代器不依赖索引

 

循环遍历: 

 //2.获取迭代器对象
        //迭代器就好比是一个箭头,默认指向集合的0索引处
        Iterator<String> it = coll.iterator();
        //3.利用循环不断的去获取集合中的每一个元素
        while(it.hasNext()){
            //4.next方法的两件事情:获取元素并移动指针
            String str = it.next();
            System.out.println(str);
        }

示例代码:(不依赖索引,而是通过指针移动的方式)

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class A03_CollectionDemo3 {
    public static void main(String[] args) {
        /*
            Collection系列集合三种通用的遍历方式:
                1.迭代器遍历
                2.增强for遍历
                3.lambda表达式遍历


             迭代器遍历相关的三个方法:
                    Iterator<E> iterator()  :获取一个迭代器对象
                    boolean hasNext()       :判断当前指向的位置是否有元素
                    E next()                :获取当前指向的元素并移动指针
        */

        //1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");

        //2.获取迭代器对象
        //迭代器就好比是一个箭头,默认指向集合的0索引处
        Iterator<String> it = coll.iterator();
        //3.利用循环不断的去获取集合中的每一个元素
        while(it.hasNext()){
            //4.next方法的两件事情:获取元素并移动指针
            String str = it.next();
            System.out.println(str);
        }

    }
}

迭代器书写的小细节:

迭代器细节注意点:

 
        迭代器的细节注意点:
            1.报错NoSuchElementException
            2.迭代器遍历完毕,指针不会复位
            3.循环中只能用一次next方法
            4.迭代器遍历时,不能用集合的方法进行增加或者删除
                暂时当做一个结论先行记忆,在今天我们会讲解源码详细的再来分析。
                如果我实在要删除:那么可以用迭代器提供的remove方法进行删除。
                如果我要添加,暂时没有办法。
       
//当上面循环结束之后,迭代器的指针已经指向了最后没有元素的位置
        //System.out.println(it.next());//NoSuchElementException

        //迭代器遍历完毕,指针不会复位
        System.out.println(it.hasNext());

        //如果我们要继续第二次遍历集合,只能再次获取一个新的迭代器对象
        Iterator<String> it2 = coll.iterator();
        while(it2.hasNext()){
            String str = it2.next();
            System.out.println(str);
        }

 



import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class A05_CollectionDemo5 {
    public static void main(String[] args) {
     

        //1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        coll.add("eee");

        //2.获取迭代器对象
        //迭代器就好比是一个箭头,默认指向集合的0索引处
        Iterator<String> it = coll.iterator();
        //3.利用循环不断的去获取集合中的每一个元素
        while(it.hasNext()){
            //4.next方法的两件事情:获取元素,并移动指针
            String str = it.next();
            if("bbb".equals(str)){
                //coll.remove("bbb");
                it.remove();
            }
        }
        System.out.println(coll);

    }
}

小结:

Interator方法:

2.2增强for循环

示例代码:

import java.util.ArrayList;
import java.util.Collection;

public class A06_CollectionDemo6 {
    public static void main(String[] args) {
       /* Collection系列集合三种通用的遍历方式:
        1.迭代器遍历
        2.增强for遍历
        3.lambda表达式遍历

        增强for格式:
            for(数据类型 变量名: 集合/数组){

            }

        快速生成方式:
            集合的名字 + for 回车

        */


        //1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("zhangsan");
        coll.add("lisi");
        coll.add("wangwu");

        //2.利用增强for进行遍历
        //注意点:
        //s其实就是一个第三方变量,在循环的过程中依次表示集合中的每一个数据
        for(String s : coll){
            s = "qqq";
        }

        System.out.println(coll);//zhangsan lisi wangwu
    }
}

 2.3Lambda表达式遍历

示例代码:

//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));

 3、小结

 

 

三、List集合


1、List集合特有的方法(操作索引的4个方法)


示例代码:

import java.util.ArrayList;
import java.util.List;

public class A01_ListDemo1 {
    public static void main(String[] args) {
       /*

        List系列集合独有的方法:
            void add(int index,E element)       在此集合中的指定位置插入指定的元素
            E remove(int index)                 删除指定索引处的元素,返回被删除的元素
            E set(int index,E element)          修改指定索引处的元素,返回被修改的元素
            E get(int index)                    返回指定索引处的元素
        */


        //1.创建一个集合
        List<String> list = new ArrayList<>();

        //2.添加元素
        list.add("aaa");
        list.add("bbb");//1
        list.add("ccc");


        //void add(int index,E element)       在此集合中的指定位置插入指定的元素
        //细节:原来索引上的元素会依次往后移
        //list.add(1,"QQQ");

        //E remove(int index)                 删除指定索引处的元素,返回被删除的元素
        //String remove = list.remove(0);
        //System.out.println(remove);//aaa


        //E set(int index,E element)          修改指定索引处的元素,返回被修改的元素
        //String result = list.set(0, "QQQ");
        //System.out.println(result);

        // E get(int index)                    返回指定索引处的元素
        //String s = list.get(0);
        //System.out.println(s);


        //3.打印集合
        System.out.println(list);


    }
}

add方法:


        //1.创建一个集合
        List<String> list = new ArrayList<>();

        //2.添加元素
        list.add("aaa");
        list.add("bbb");//1
        list.add("ccc");


        //void add(int index,E element)       在此集合中的指定位置插入指定的元素
        //细节:原来索引上的元素会依次往后移
        list.add(1,"QQQ");

        

remove方法:


        E remove(int index)                 //删除指定索引处的元素,返回被删除的元素
        String remove = list.remove(0);
        System.out.println(remove);//aaa


List删除的小细节:

//List系列集合中的两个删除的方法
        //1.直接删除元素
        //2.通过索引进行删除

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

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


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

        //list.remove(1);


        //手动装箱,手动把基本数据类型的1,变成Integer类型
        Integer i = Integer.valueOf(1);

        list.remove(i);

        System.out.println(list);

set & get方法:


        //E set(int index,E element)          修改指定索引处的元素,返回被修改的元素
        //String result = list.set(0, "QQQ");
        //System.out.println(result);

        // E get(int index)                    返回指定索引处的元素
        //String s = list.get(0);
        //System.out.println(s);

2、List集合的遍历方式(5种)

  • 迭代器遍历
  • 列表迭代器遍历
  • 增强for遍历
  • Lambda表达式遍历
  • 普通for循环(因为List集合存在索引)

2.1迭代器遍历:


        /*
            List系列集合的五种遍历方式:
                1.迭代器
                2.列表迭代器
                3.增强for
                4.Lambda表达式
                5.普通for循环
         */


        //创建集合并添加元素
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");

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


        

2.2增强for:


        //2.增强for
        //下面的变量s,其实就是一个第三方的变量而已。
        //在循环的过程中,依次表示集合中的每一个元素
        for (String s : list) {
            System.out.println(s);
        }

        

2.3Lambda表达式



        //3.Lambda表达式
        //forEach方法的底层其实就是一个循环遍历,依次得到集合中的每一个元素
        //并把每一个元素传递给下面的accept方法
        //accept方法的形参s,依次表示集合中的每一个元素
        list.forEach(s->System.out.println(s) );


       
   

2.4普通for循环


        //4.普通for循环
        //size方法跟get方法还有循环结合的方式,利用索引获取到集合中的每一个元素
        for (int i = 0; i < list.size(); i++) {
            //i:依次表示集合中的每一个索引
            String s = list.get(i);
            System.out.println(s);
        }

    

2.5列表迭代器(ListIterator,继承于Iterator)


        // 5.列表迭代器
        //获取一个列表迭代器的对象,里面的指针默认也是指向0索引的

        //额外添加了一个方法:在遍历的过程中,可以添加元素
        ListIterator<String> it = list.listIterator();
        while(it.hasNext()){
            String str = it.next();
            if("bbb".equals(str)){
                //qqq
                it.add("qqq");
            }
        }
   

但迭代器默认指向0索引,想要使用previous方法需要先移动到后面

小结

四、数据结构(常见有8种)

1、什么是数据结构呢?

数据结构就是计算机存储、组织数据的方式

不同的业务场景要选择不同的数据结构

2、数据结构概述

常见的数据结构:

栈、队列、数组、链表、二叉树、二叉树查找


3、栈(后进先出,先进后出)


 

4、队列(先进先出,后进后出)

  • 数据从后端进入队列模型的过程称为:入队列
  • 数据从前端离开队列模型的过程称为:出队列


5、栈与队列小结


6、数组


7、链表(与数组相对)

双向链表可以提高查询效率:

小结

五、ArrayList原码分析

 1、ArrayList集合底层原理

2、ArrayList源码分析

idea快捷键:Alt + 7:列出方法大纲

添加的数据长度不超过10:

 一次添加多个,超过10,但不超过15:

六、LinkedList集合

1、LinkedList特有方法

2、LinkedList源码分析

3、迭代器源码分析

 

modCount:集合变化的次数

expectedModCount:创建对象时,传递过来的次数

结论:
在以后如何避免并发修改异常
在使用迭代器或者是增强for遍历集合的过程中,不要使用集合的方法去添加
或者删除元素即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1436929.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android实现底部导航栏方法(Navigation篇)

Navigation实现底部导航栏 前言导入和基本使用导入基础使用创建nav文件编辑Nav文件添加页面&#xff08;代码版&#xff09;添加页面&#xff08;图解版&#xff09; 创建导航动作 action创建action&#xff08;代码版&#xff09;创建action&#xff08;图解版&#xff09; 编…

Linux的进程信号

注意&#xff1a;首先需要提醒一个事情&#xff0c;本节提及的进程信号和下节的信号量没有任何关系&#xff0c;请您区分对待。 1.信号概念 1.1.生活中的信号 我们在生活中通过体验现实&#xff0c;记忆了一些信号和对应的处理动作&#xff0c;这意味着信号有以下相关的特点&…

上位机图像处理和嵌入式模块部署(统计函数执行时间)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 和pc上位机相比较&#xff0c;嵌入式设备的计算资源很多时候都是不足的。但是&#xff0c;嵌入式设备胜在稳定性和成本上面&#xff0c;这方面又是…

【XR806开发板试用】xr806使用tcp socket与手机通信

本文为极术社区XR806开发板活动试用文章。 参考&#xff1a;基于星辰处理器的全志XR806开源鸿蒙开发板上手体验 搭建环境。并成功编译。 项目源码 &#xff1a; https://gitee.com/kingwho/smart-home 在同一个局域网中&#xff0c;手机与xr806连接后&#xff0c;手机 APP 每隔…

lnmp一键安装包+wordpress

理论知识 1. LNMP组成介绍​ LNMP代表的是Linux系统下NginxMySQLPHP组成的动态网站系统解决方案。如图所示&#xff0c;Linux是目前最流行的免费操作系统&#xff1b;Nginx性能稳定、功能丰富、处理静态文件速度快且消耗系统的资源极少&#xff1b;MySQL是一个性能卓越、服务稳…

手拉手Vue3+vite引入echarts

技术栈springboot3hutool-alloshi-coreVue3viteechartsTailwindCSS软件版本IDEAIntelliJ IDEA 2022.2.1JDK17Spring Boot3.1hutool-all5.8.18oshi-core6.4.1Vue35.0.10vite5.0.10axios1.6.7echarts5.4.3 ECharts是一个使用 JavaScript 实现的开源可视化库&#xff0c;可以流畅…

awd总结

总结&#xff1a; 由于是第一次参加AWD比赛&#xff0c;各方面经验都不足&#xff0c;在参赛的前几天也是疯狂搜集各种脚本、框架、工具等&#xff0c;同时也参考b站的视频进行学习&#xff0c;我发现就是还是实操才能更快的学习 我觉得就是我前期的准备工作不足&#xff0c;…

stm32软件安装以及创建工程

文章目录 前言一、软件安装软件破解 二、创建工程三、创建项目创建组配置启动文件添加到组 为项目添加头文件路径创建源文件&#xff08;main函数文件&#xff09;使用寄存器配置引脚拼接好STLINK与stm32最小电路板的接线编写程序配置STLink下载程序配置寄存器配置13号端口&…

智能化运维发展现状?智能化运维方向有哪些?

智能运维方向主要包括人工运维、自动运维和智能运维三个阶段。从以下几个方面可以简要介绍智能运维的发展情况&#xff1a;  市场参与者众多&#xff1a;我国智能运维领域参与者众多&#xff0c;市场份额相对较低。华为、浪潮云、联想等硬件制造商在市场上占有很大份额。  …

c语言游戏实战(3):三子棋

前言&#xff1a; 三子棋是一种民间传统游戏&#xff0c;又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小&#xff0c;三子棋在很多时候会出现和…

vulnhub中Beelzebub靶机

渗透思路 一.信息收集1.网段探测2.端口探测3.常见漏洞扫描4.目录扫描5.web页面分析 二.渗透继续目录扫描ssh连接提权提权&#xff0c;flag 一.信息收集 1.网段探测 ┌──(root㉿kali)-[~] └─# nmap -Pn 192.168.0.0/24 --min-rate 10000 Starting …

day28打卡

day28打卡 93. 复原 IP 地址 见注释 class Solution { public:vector<string> ret;vector<string> restoreIpAddresses(string s) {string ip;dfs(s, 0, ip);return ret;}//n记录小数点个数void dfs(string s, int n, string ip){//n为4if(n 4){//如果字符s没有…

2024Node.js零基础教程(小白友好型),nodejs新手到高手,(四)NodeJS入门——网络基础概念

041_网络基础概念_IP的介绍 hello&#xff0c;大家好&#xff0c;我们来一起认识一下IP。 在开始介绍 IP 之前&#xff0c;我们首先来介绍一个场景&#xff0c;方便大家去理解 IP 这个概念。比如这会儿强哥正在成都&#xff0c;然后还有另外一个小伙伴&#xff0c;谁呢&#x…

数据库分库分表:提升系统性能的必由之路

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 数据库分库分表&#xff1a;提升系统性能的必由之路 前言为什么分库分表是必要的分库分表的基本概念和原理性能提升和负载均衡 前言 在数字化时代&#xff0c;数据被认为是企业最宝贵的资产之一。然而…

STA双WiFi连接

STA双WiFi连接 1、STA/STA双WiFi开关1.1 相关属性1.2 STA/STA支持判断 2、STA双WiFi命令测试2.1 adb shell cmd wifi add-suggestion guest_5G wpa3 12345678 -p2.2 adb shell cmd wifi remove-suggestion guest_5G2.3 查看dumpsys wifi信息WifiConfigStore 3、STA双WiFi连接流…

Graal编译器和GraalVM虚拟机

文章目录 说明Java程序执行流程JVM的语言无关性JVM的执行流程执行引擎的两种行为&#xff1a;解释执行和编译热点代码和热点代码探测方式热点代码热点代码探测方式热点代码探测方式流程 HotSpotVM内嵌两个JIT编译器Graal编译器GraalVMGraalVM虚拟机安装和体验GraalVM的下载和安…

【JavaEE】_传输层协议UDP与TCP

目录 1. 开发中常见的数据组织格式 1.1 XML 1.2 JSON 1.3 Protobuf 2. 端口号 3. UDP协议 4. TCP协议 4.1 特点 4.2 TCP报文格式 4.3 TCP可靠性机制 4.3.1 确认应答机制 4.3.2 超时重传机制 4.3.2.1 丢包的两种情况 4.3.2.2 重传时间 4.3.3 连接管理机制 4.3.3…

【Flink入门修炼】1-2 Mac 搭建 Flink 源码阅读环境

在后面学习 Flink 相关知识时&#xff0c;会深入源码探究其实现机制。因此&#xff0c;需要现在本地配置好源码阅读环境。 本文搭建环境&#xff1a; Mac M1&#xff08;Apple Silicon&#xff09;Java 8IDEAFlink 官方源码 一、 下载 Flink 源码 github 地址&#xff1a;h…

【Vue3+Vite】Vue生命周期与组件 快速学习 第三期

文章目录 一、Vue生命周期1.1 生命周期简介1.2 生命周期案例 二、Vue组件2.1 组件基础2.2 组件化入门案例2.3 组件之间传递数据2.3.1父传子2.3.2 子传父2.3.3 兄弟传参 总结 一、Vue生命周期 1.1 生命周期简介 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤&#xf…

UE5 获得频谱让nigara随音乐律动

参考视频:UE - Niagara实现可视化音乐动态粒子效果 案例演示及教程_哔哩哔哩_bilibili 先创建一个Niagara 在Properties的Sim Target改为GPU,Calculate Bounds Mode改为Fixed模式 生成的数量改为1000 这里的BoxSize可以选择修改,具体作用是粒子初始生成的范围 Drag,阻力,用来限…