Java入门到入土(集合篇)

news2024/11/15 11:18:45

前言
   初出茅庐
      Collection集合特点
      Map集合特点
   牛刀小试
      List集合用法
         迭代器原理
      Set集合用法
      Map集合用法
   追根溯源
      List集合解析
      Set集合解析
      Map集合解析
结束语

前言

Java中用来批量存储数据的方式有两种。一种是数组,而另一种就是较为高级的集合。数组在Java前段基础部分讲过很多,这里先回顾一下,数组有几个很明显的特点,1、严格规定数据单一存放类型。2、长度在创建时就固定不可更改(在不使用额外空间下)。3、其底层数据存放地址是连续的。集合其实和数组很像,但又不完全是,两者还是有区别的,通俗的理解就是集合是数组的Plus版本。

初出茅庐

当我们要去学一个未知的东西时,首先并不是如何使用它,而是先要了解它,知道它是什么,它的继承了什么,又实现了什么,它的大体结构是什么样的。那么我画了一张结构树,这里包含了我们Java基础所必须要了解并掌握的几个常用的集合类。
在这里插入图片描述
你也可以自己通过快捷键Ctrl+n进行类的查找,并且通过找到父类或实现类进行了解类的结构。
在这里插入图片描述
在这里插入图片描述
大体关系就如上图所说,一个Collection接口和一个Map接口包揽了几乎所有的常用集合,但是在这两个接口下又有不同的子类接口进行实现,更加准确的分类了不同功能和特性的集合实现类,譬如:Collection下就有List、Set和Queue这三个子接口,分别对应不同的功能的集合实现类,开发者更具需求进行逐个实现即可。

Collection接口特点

List接口旗下的集合里的元素是有序且可重复的,采用索引值进行存储和定位元素
Set接口旗下的集合里的元素是无序且不可重复的,采用hash码进行存储元素
Queue接口不常用,这里暂不做介绍

Map接口特点

map集合和Collection旗下的集合存储元素方式不同,map采用key-value,一键一值对应的方式来存储元素。key和value均为Object类型,灵活性较强

牛刀小试

List集合

先演示List接口下常用的ArrayList类的一些基本用法

//创建集合
        ArrayList<String> list = new ArrayList<>();

        //添加元素入集合
        list.add("第一个元素");
        list.add("第二个元素");

        //获取元素
        String s1 = list.get(0);
        String s2 = list.get(1);

        //遍历list集合内所有的元素
        //第一种常规根据长度进行逐一遍历的方式
        int size = list.size(); //获取list集合大小,就是元素个数
        for (int i = 0; i <size; i++) {     //使用索引逐一按顺序输出
            String s = list.get(i);
            System.out.println(s);
        }

        //第二种使用迭代器进行遍历输出
        Iterator<String> iterator = list.iterator();    //获取一个迭代器对象
        while (iterator.hasNext()){                     //判断集合中当前位置下一个是否存在元素
            String next = iterator.next();              //获取当前位置的下一个元素
            System.out.println(next);
        }

        //删除元素
        list.remove(0); //根据索引值删除元素
        list.remove("第二个元素");   //根据元素值删除元素
        System.out.println(list.size()); //验证是否删除成功

List集合的典型特征就是有序且可重复,所以可以通过索引来取值。遍历也有两种不同的方式,都可以达到相同的效果。一种通过集合的大小逐一遍历内部的元素。另一种通过创建对应的迭代器对象,逐一迭代元素。

迭代器原理

关于迭代器工作原理,由下图解释:
在这里插入图片描述

Set集合

下面演示Set集合的其中一个常用的HashSet实现类的一些基本的用法

//实例化一个Set接口旗下的HashSet实现类
        HashSet<String> set = new HashSet<>();

        //向HashSet里存放值
        set.add("甲");
        set.add("乙");

        //由于Set是无序所以没有索引,只能用迭代器迭代出来
        Iterator<String> iterator1 = set.iterator();
        while (iterator1.hasNext()){
            String next = iterator1.next();
            System.out.println(next);
        }

        //移除值
        set.remove("甲");
        set.remove("乙");
        System.out.println(set.size());

Set由于是无序的,所以就不会像List集合那样存在索引可以取值,只能使用迭代器进行取值,因为其是通过每存一个元素就计算其的哈希码算出存放位置,所以也证明了其内部的元素不可能重复,因为相同的值哈希码必然相同。

map集合

下面是map集合,通过map接口下的一个常用的HashMap实现类进行基本的用法进行演示说明。

//创建Map集合
        Map<String,Integer> map = new HashMap<String,Integer>();

        //添加元素到map集合中
        map.put("第一个数",1);
        map.put("第二个数",2);

        //第一种方式
        Set<String> set1 = map.keySet();
        for (String s : set1){
            System.out.println("key="+s+",value="+map.get(s));
        }

        //第二种
        for (Map.Entry<String,Integer> entry: map.entrySet()) {
            System.out.println("key="+entry.getKey()+",value="+entry.getValue());
        }

        //第三种
        // 通过Map.entrySet使用iterator遍历key和value
        Iterator<Map.Entry<String, Integer>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Integer> entry = entries.next();
            System.out.println(entry);
        }

        //移除元素
        map.remove("第一个数");
        map.remove("第二个数");
        System.out.println(map.size());

map集合比前面的两种集合略微复杂一些,但是功能也会更加强大和高效。map存放元素是以键值对的形式进行存放,一个键对应一个值,键和值分别通过Set集合和List集合进行设计并存放。其迭代方式有三种,一种是通过先取key值,再通过key值,取出value值。第二种通过获取map内部的一个封闭接口拿到所有的key-value值的对象,再逐一获取对应的key和value值。第三种其实就是把foreach遍历换成了iterator迭代器遍历。原理和第二种类似。

追根溯源

集合的大概结构和基本的用法我们都已经清楚了,下面我们看看如此强大的集合对象究竟是怎么形成的。通过点开集合的源码我们就可以一目了然其内部构造了。

ArrayList解析

首先看它的底层初始构造,我们打开类的搜索项,搜索ArrayList类,
在这里插入图片描述
我们可以看到在创建ArrayList集合对象底层其实创建一个数组,也就是说集合底层就是个数组,如果但是集合和数组有什么区别呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一开始先创建一个默认容量为10的数组进行存储,如果存储的数据量超过10的话,就会进行扩容,扩容量为1.5倍(oldCapacity >> 1)。普通数组长度是固定,但是List集合对象长度是可以变化的。下面我们看他如何取出数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当它get取这个索引所指向的值时,会先进行checkIndex方法进行判断该索引是否越界,越界就抛出越界异常,否则就通过数组取出该索引的值。

Set解析

Set常用接口的实现类HashSet的底层其实是一个Map集合,谈到了map集合下面就会介绍,可以先看map集合的解析,看完后再回来看这里就清楚了。Set结构与List是完全不同的
在这里插入图片描述
再观察他的存值特点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
set存储数据时用到了hash方法计算哈希码的方式进行存储,这样set集合就不会出现重复的元素了,但是同样也带来没有索引值取数据困难的局面。

Map解析

这里主讲map集合的底层创建以及扩容机制。map是一个内部比较复杂集合,因为他的功能比较多结构精巧。他的底层实现用到了负载因子,根据计算阈值来创建,公式为阈值=负载因子*容量,这负载因子默认为0.75,
在这里插入图片描述
在这里插入图片描述
我们可以看到这个对象初始化只是把负载因子赋值了,我们下面再看它的添加元素方法
在这里插入图片描述
这里通过把key和value作为参数进行传到真正实现存储的putVal方法
在这里插入图片描述
在这里插入图片描述

我们可以看到这里创建了两个数组进行存储,并且下面两步将需要储存的传来的参数key和value进行存储到刚创建的数组中进行保存
在这里插入图片描述
我们可以看到在添加元素时,在没有创建实例时初始化后,put方法里会判断容量是否为空,调用resize方法第一次赋值容量赋值为16,阈值赋值为0.7516=12。每当超过阈值就会进行扩容,之后每次扩容都是两倍。总之容量和阈值之间保持0.75的比例
以上的是无参构造器实现及扩容机制,下面看有参构造器的实现:
在这里插入图片描述
在这里插入图片描述
有参构造器构造集合时,以上该种构造器就不会用默认的系统容量,则会使用开发者所定义的参数容量,但会使用系统默认的负载因子,下面会判断是否超过最大容量,超出则赋予系统默认最大支持的容量。并且在最后一行给阈值进行了赋值
在这里插入图片描述
在这里插入图片描述
注意:初始容量设置为2的倍数的话是自定义容量,如果不是则容量是系统根据以上算法算出离设定参数最近的2的n倍的容量。但是最后编译器仍会把我们设置的容量屏蔽,假设设置的初始容量为8,那么阈值就是8
0.75=6,此时扩容就会造成内存浪费,一般系统把容量定义为16。

结束语

以上就是Java集合篇的三大常用集合的归纳、常用功能和解析,除此之外还有很多其他特色功能的集合,以后也会根据需求撰写更多的相关内容。

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

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

相关文章

mac 怎么批量修改文件后缀?

mac 批量修改文件后缀的方法教程~平时在电脑上使用文件的时候&#xff0c;经常需要对文件的后缀名进行修改&#xff0c;文件后缀名也就是文件扩展名&#xff0c;如果仅是单纯的修改文件后缀名&#xff0c;并不涉及格式转换的情况下&#xff0c;其实方法很简单&#xff0c;只需要…

ZBrush 3D游戏建模教程:创建女武士模型

推荐&#xff1a;将NSDT场景编辑器加入你的3D工具链 3D工具集&#xff1a;NSDT简石数字孪生 介绍 在本教程中&#xff0c;演示创建实时武士角色的流程&#xff0c;该流程基于 Kati Sarin S 的原始概念。我将使用各种各样的软件&#xff0c;如ZBrush&#xff0c;Maya&#xff…

微信小程序外卖管理的设计与实现(论文+源码)_kaic

摘要 随着互联网技术的不断更新和发展&#xff0c;人们的生活水平也在不断的提高&#xff0c;人们对互联网的依赖越来越紧密&#xff0c;尤其是网上外卖也越来越习惯了。它的功能包括在主页上列出出售的外卖。您也可以直接在首页顶部搜索想要的产品&#xff0c;如果余额不足&am…

信号与系统课程实验报告: 连续信号及其傅里叶变换的编程

一、实验目的 认识并熟悉Matlab软件的使用&#xff0c;并能利用其进行编程利用Matlab实现连续信号的表示掌握数值法和符号法进行编程实现连续周期信号的傅里叶级数求解编程算法实现连续信号的傅里叶变换求解编程算法理解Matlab代码的具体意义并熟练使用利用Matlab对LTI系统的频…

Maven依赖管理(核心)

依赖配置 依赖&#xff1a;指当前项目运行所需要的jar包&#xff0c;一个项目可以引入多个依赖配置&#xff1a; 在pom.xml中编写<dependencies>标签在<dependencies>标签中使用<dependency>引入坐标定义坐标的groupId、artifacId、version点击刷新按钮&…

二叉树层序遍历

目录 一、什么是层序遍历 二、层序遍历的实现 三、判断一棵树是否为完全二叉树 总结&#xff1a; 学习二叉树结构&#xff0c;最简单的就是遍历。 所谓二叉树遍历就是按照某种规则对二叉树中的节点进行相应操作&#xff0c;每个节点值操作一次。 遍历是二叉树的重要运算之…

深入篇【C++】手搓模拟实现string类(详细剖析常见的各接口):【400行代码实现】

深入篇【C】手搓模拟实现string类(包含常见的各接口&#xff09;&#xff1a;【400行代码实现】 【string类模拟实现完整代码】Ⅰ.构造/析构1.string()2.operator3.~string() Ⅱ.访问遍历1.operator[]2.iterator3.范围for Ⅲ.增操作1.push_back()2.append()3.operator4.insert(…

Harbor未授权创建管理员

人处在幸福与不幸交织的矛盾之中&#xff0c;反而使内心有一种更为深刻的痛苦&#xff0c;看来近在眼前的幸福而实际上又远得相当渺茫&#xff0c;海市蜃楼。放不得抓不住。 漏洞描述 近日&#xff0c;镜像仓库Harbor爆出任意管理员注册漏洞&#xff0c;攻击者在请求中构造特…

eNSP-VLAN多端口成员模式+DHCP

VLAN多端口成员模式DHCP 文章目录 VLAN多端口成员模式DHCP一、题目要求二、题目分析三、拓扑结构四、基本配置五、测试验证1.网段测试2.访问测试 一、题目要求 1、PC1和pc3所在接口为Access接口&#xff0c;PC2/4/5/6处于同一网段&#xff0c;其中PC2可以访问PC4/5/6&#xff…

Webkit内核探究——Webkit CSS实现

文章目录 前言1、CSS是什么2、CSS实现模型3、CSS默认样式表4、CSS解析5、CSS如何作用于Render Tree 前言 CSS在Webkit中的实现属于相对独立的一个模块&#xff0c;注意这里说的是相对。 CSS在Webkit中的作用自然是不言而喻的&#xff0c;在Web早期&#xff0c;文档的结构和样…

【运维工程师学习五】数据库

【运维工程师学习五】数据库 1、常用的关系型数据库2、C/S结构3、MariaDB图形客户端4、安装MariaDB5、启动MariaDB及验证启动是否成功6、验证启动——端口7、验证启动——进程8、MariaDB配置文件路径主配置文件解读&#xff1a; 9、MariaDB的配置选项10、MariaDB客户端连接1、在…

Windows下 Oracle 12c 安装保姆级图文详解

Windows下 Oracle 12c 安装步骤如下&#xff1a; 1、将压缩包“winx64_12c_database_1of2.zip“和“winx64_12c_database_2of2.zip”解压到同一目录“database”目录。 2、双击“database”目录下的“setup.exe"&#xff0c;软件会加载并初步校验系统是否可以达到了数据…

华为云出品《深入理解高并发编程:Java线程池核心技术》电子书发布

系统拆解线程池核心源码的开源小册 透过源码看清线程池背后的设计和思路 详细解析AQS并发工具类 点击下方链接进入官网&#xff0c;右上角搜索框搜索“《深入理解高并发编程&#xff1a;Java线程池核心技术》” 即可获取下载。 https://auth.huaweicloud.com/authui/login…

01-线性表 (数据结构和算法)

要点&#xff1a; 程序 数据结构 算法 一、数据结构的概述 程序 数据结构 算法 数据结构&#xff1a;计算机存储、组织数据的方式 算法&#xff1a;处理数据的方式 1.1 基本概念和术语 1、数据 数据&#xff08;data&#xff09;&#xff1a;所有能够输入到计算机中…

【Method】稀疏与压缩感知 | 图像稀疏性及压缩感知方法白话讲解

【Method】稀疏与压缩感知 | 图像稀疏性及压缩感知方法白话讲解 文章目录 【Method】稀疏与压缩感知 | 图像稀疏性及压缩感知方法白话讲解1. 为什么图像是可压缩的&#xff1a;图像空间的广阔2. 什么是Sparsity&#xff1f;3.压缩感知&#xff1a;简介4.压缩感知&#xff1a;数…

matlab学习指南(3):最全MATLAB工具箱Toolbox下载地址大汇总

&#x1f305;*&#x1f539;** φ(゜▽゜*)♪ **&#x1f539;*&#x1f305; 欢迎来到馒头侠的博客&#xff0c;该类目主要讲数学建模的知识&#xff0c;大家一起学习&#xff0c;联系最后的横幅&#xff01; 喜欢的朋友可以关注下&#xff0c;私信下次更新不迷路&#xff0…

火车头采集器AI伪原创【php源码】

本文介绍火车头采集器AI伪原创&#xff0c;对于新媒体从业者来说&#xff0c;会写文章是最基本的职业技能&#xff0c;而伪原创是我们经常使用的技能。今天我要讲的是SEO标兵如何在伪原创上创作文章。 首先&#xff0c;原创性永远是最好的&#xff0c;更受读者欢迎。伪原创的出…

Microsoft Dynamics 365:VS2019引用BC发布的SOAP服务

1、搜索网页服务 2、点击新建 3、选择对象类型&#xff1a;页面、单元、查询&#xff0c;输入ID&#xff0c;勾选即可发布服务 4、复制SOAP URL到浏览器里看看是否可以访问&#xff0c;这样就OK的 5、 右键添加服务引用 6、选择高级 7、添加web引用 8、服务地址粘贴进去查找服…

云原生监控——VictoriaMetrics

1.简介 VictoriaMetrics是一个快速高效且可扩展的监控解决方案和时序数据库&#xff0c;可以作为Prometheus的长期远端存储&#xff0c;具备的特性有&#xff1a; 支持prometheus查询api&#xff0c;同时实现了一个metricsql 查询语言支持全局查询视图&#xff0c;支持多prom…

uniapp引用leaflet地图实现方案

最近在做uniapp实现的移动端app&#xff0c;其中一些模块需要gis地图&#xff0c;在最开始的时候我尝试了使用uniapp官方自带的map组件&#xff0c;但是非常不好用。 后来又引用了mars2d来实现&#xff0c;但是发现这种引用方式会出现一个bug&#xff0c;在浏览器当中使用的时候…