JAVA-编程基础-10-集合

news2024/11/24 13:37:31

Lison <dreamlison@163.com>, v1.0.0, 2023.04.23

JAVA-编程基础-10-集合

文章目录

  • JAVA-编程基础-10-集合
    • List、Set、Map、队列全面解析
      • List
        • ArrayList
          • 创建ArrayList
        • 向ArrayList中添加元素

List、Set、Map、队列全面解析

在这里插入图片描述

Java 集合框架可以分为两条大的支线:”

  • Collection,主要由 List、Set、Queue 组成,List 代表有序、可重复的集合,典型代表就是封装了动态数组的 ArrayList 和封装了链表的 LinkedList;Set 代表无序、不可重复的集合,典型代表就是 HashSet 和 TreeSet;Queue 代表队列,典型代表就是双端队列 ArrayDeque,以及优先级队列 PriorityQueue。
  • Map,代表键值对的集合,典型代表就是 HashMap。

List

List 的特点是存取有序,可以存放重复的元素,可以用下标对元素进行操作。

ArrayList

// 创建一个集合
ArrayList<String> list = new ArrayList<String>();
// 添加元素
list.add("Li");
list.add("Cun");
list.add("Lison");

// 遍历集合 for 循环
for (int i = 0; i < list.size(); i++) {
    String s = list.get(i);
    System.out.println(s);
}
// 遍历集合 for each
for (String s : list) {
    System.out.println(s);
}

// 删除元素
list.remove(1);
// 遍历集合
for (String s : list) {
    System.out.println(s);
}

// 修改元素
list.set(1, "Lison520");
// 遍历集合
for (String s : list) {
    System.out.println(s);
}

简单介绍一下 ArrayList 的特征

  • ArrayList 是由数组实现的,支持随机存取,也就是可以通过下标直接存取元素;
  • 从尾部插入和删除元素会比较快捷,从中间插入和删除元素会比较低效,因为涉及到数组元素的复制和移动;
  • 如果内部数组的容量不足时会自动扩容,因此当元素非常庞大的时候,效率会比较低。
创建ArrayList
ArrayList<String> alist = new ArrayList<String>();

可以通过上面的语句来创建一个字符串类型的 ArrayList(通过尖括号来限定 ArrayList 中元素的类型,如果尝试添加其他类型的元素,将会产生编译错误),更简化的写法如下:

List<String> alist = new ArrayList<>();

由于 ArrayList 实现了 List 接口,所以 alist 变量的类型可以是 List 类型;new 关键字声明后的尖括号中可以不再指定元素的类型,因为编译器可以通过前面尖括号中的类型进行智能推断

此时会调用无参构造方法(见下面的代码)创建一个空的数组,常量DEFAULTCAPACITY_EMPTY_ELEMENTDATA的值为 {}

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

如果非常确定 ArrayList 中元素的个数,在创建的时候还可以指定初始大小。

List<String> alist = new ArrayList<>(20);

这样做的好处是,可以有效地避免在添加新的元素时进行不必要的扩容。

向ArrayList中添加元素

可以通过 add() 方法向 ArrayList 中添加一个元素:

alist.add("Lison");
堆栈过程图示:
add(element)
└── if (size == elementData.length) // 判断是否需要扩容
    ├── grow(minCapacity) // 扩容
    │   └── newCapacity = oldCapacity + (oldCapacity >> 1) // 计算新的数组容量
    │   └── Arrays.copyOf(elementData, newCapacity) // 创建新的数组
    ├── elementData[size++] = element; // 添加新元素
    └── return true; // 添加成功

先是 add() 方法的源码

/** jdk1.8
 * 将指定元素添加到 ArrayList 的末尾
 * @param e 要添加的元素
 * @return 添加成功返回 true
 */
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // 确保 ArrayList 能够容纳新的元素
    elementData[size++] = e; // 在 ArrayList 的末尾添加指定元素
    return true;
}

参数 e 为要添加的元素,此时的值为“Lison520”,size 为 ArrayList 的长度,此时为 0。

/**
 * 确保 ArrayList 能够容纳指定容量的元素
 * @param minCapacity 指定容量的最小值
 */
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // 如果 elementData 还是默认的空数组
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 使用 DEFAULT_CAPACITY 和指定容量的最小值中的较大值
    }

    ensureExplicitCapacity(minCapacity); // 确保容量能够容纳指定容量的元素
}

此时:

  • 参数 minCapacity 为 1(size+1 传过来的)
  • elementData 为存放 ArrayList 元素的底层数组,前面声明 ArrayList 的时候讲过了,此时为空 {}
  • DEFAULTCAPACITY_EMPTY_ELEMENTDATA 前面也讲过了,为 {}

所以,if 条件此时为 true,if 语句minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity)要执行。

DEFAULT_CAPACITY 为 10(见下面的代码),所以执行完这行代码后,minCapacity 为 10,Math.max() 方法的作用是取两个当中最大的那个。

private static final int DEFAULT_CAPACITY = 10;

执行 ensureExplicitCapacity() 方法,来看一下源码:

/**
 * 检查并确保集合容量足够,如果需要则增加集合容量。
 *
 * @param minCapacity 所需最小容量
 */
private void ensureExplicitCapacity(int minCapacity) {
    // 检查是否超出了数组范围,确保不会溢出
    if (minCapacity - elementData.length > 0)
        // 如果需要增加容量,则调用 grow 方法
        grow(minCapacity);
}

此时:

  • 参数 minCapacity 为 10
  • elementData.length 为 0(数组为空)

所以 10-0>0,if 条件为 true,进入 if 语句执行 grow() 方法,来看源码:

/**
 * 扩容 ArrayList 的方法,确保能够容纳指定容量的元素
 * @param minCapacity 指定容量的最小值
 */
private void grow(int minCapacity) {
    // 检查是否会导致溢出,oldCapacity 为当前数组长度
    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); // 扩容至数组的最大长度
    // 将当前数组复制到一个新数组中,长度为 newCapacity
    elementData = Arrays.copyOf(elementData, newCapacity);
}

此时:

  • 参数 minCapacity 为 10
  • 变量 oldCapacity 为 0

所以 newCapacity 也为 0,于是 newCapacity - minCapacity 等于 -10 小于 0,于是第一个 if 条件为 true,执行第一个 if 语句 newCapacity = minCapacity,然后 newCapacity 为 10。

紧接着执行 elementData = Arrays.copyOf(elementData, newCapacity);,也就是进行数组的第一次扩容,长度为 10。

回到 add() 方法:

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}

执行 elementData[size++] = e

此时:

  • size 为 0
  • e 为 “Lison520”

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

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

相关文章

OpenSIPS 注册终端 30s 自动挂断问题

文章目录 1. 背景2. 问题分析3. 案例解决 1. 背景 在开发呼叫中心应用时&#xff0c;使用 OpenSIPS 作为 SIP 注册服务器&#xff0c;测试发现偶现电话接通后 30s 左右自动挂断的问题。一个正常的 SIP 注册及呼叫流程如下所示&#xff0c;可以看到 OpenSIPS 作为转发层只负责代…

Spark Standalone环境搭建及测试

&#x1f947;&#x1f947;【大数据学习记录篇】-持续更新中~&#x1f947;&#x1f947; 篇一&#xff1a;Linux系统下配置java环境 篇二&#xff1a;hadoop伪分布式搭建&#xff08;超详细&#xff09; 篇三&#xff1a;hadoop完全分布式集群搭建&#xff08;超详细&#xf…

Unity 之 GameObject.Find()在场景中查找指定名称的游戏对象

文章目录 GameObject.Find 是 Unity 中的一个函数&#xff0c;用于在场景中查找指定名称的游戏对象。这个函数的主要作用是根据游戏对象的名称来查找并返回一个引用&#xff0c;使您能够在代码中操作该对象。以下是有关 GameObject.Find 的详细介绍&#xff1a; 函数签名&…

rust actix-web定义中间件(middleware)记录接口耗时(接口耗时中间件和鉴权中间件)

文章目录 Actix-web定义中间件(middleware)记录接口耗时中间件简介中间件添加的两种方式&#xff08;接口耗时中间件&#xff09;使用wrap_fn 闭包实现使用warp struct实现中间件调用顺序actix自带的接口耗时中间件 鉴权中间件 Actix-web定义中间件(middleware)记录接口耗时 …

一文全懂!带你了解芯片“流片”!

一、流片是什么&#xff1f; 流片(tape-out)是指通过一系列工艺步骤在流水线上制造芯片&#xff0c;是集成电路设计的最后环节&#xff0c;也就是送交制造。 流片即为"试生产"&#xff0c;简单来说就是设计完电路以后&#xff0c;先生产几片几十片&#xff0c;供测试…

Packet_Tracer的使用

一、实验目的&#xff1a; 通过该实验了解Packet Tracer的使用方法&#xff0c;能够用Packet Tracer建立和模拟网络模型。 二、主要任务&#xff1a; 1.熟悉PT的界面&#xff0c;了解按键用途。 2.尝试自己建立一个小型网络&#xff0c;并测试连通性。 3.学习P…

STM32--USART串口

文章目录 通信接口串口通信硬件电路电平标准参数时序 USART主要特性框图 数据帧发送器 波特率发生器SWART串口发送与接收工程串口收发数据包 通信接口 通信接口是指连接中央处理器&#xff08;CPU&#xff09;和标准通信子系统之间的接口&#xff0c;用于实现数据和控制信息在不…

【JVM 内存结构 | 程序计数器】

内存结构 前言简介程序计数器定义作用特点示例应用场景 主页传送门&#xff1a;&#x1f4c0; 传送 前言 Java 虚拟机的内存空间由 堆、栈、方法区、程序计数器和本地方法栈五部分组成。 简介 JVM&#xff08;Java Virtual Machine&#xff09;内存结构包括以下几个部分&#…

关于CC2652的看门狗和系统时钟的我呢

看门狗 可以在CCS的syscfg的ui中配置&#xff0c;如下图 如果想看相关例程&#xff0c;可以电极最顶部watchdog旁边的问号 相关问题&#xff1a; 例程中没有添加hw_wdt的头文件&#xff0c;需要#include <ti/devices/cc13x2_cc26x2/inc/hw_wdt.h>&#xff0c;否则在获…

全面介绍ERP采购审批管理

在现代企业中&#xff0c;采购管理对于保障企业正常运营和维护供应链的稳定性至关重要。然而&#xff0c;传统的手动采购审批流程常常存在效率低下、易出错和缺乏可追溯性等问题。为了解决这些问题&#xff0c;越来越多的企业选择采用ERP采购审批管理方法&#xff0c;以实现更高…

CentOS7 TAR安装 EMQX(MQTT)

1、软件下载 官网 --> 右上角[免费试用] --> EMQX 下载 --> EMQX 开源版 --> 选择版本 系统 --> [免费下载] 选择 tar.gz amd64 --> [立即下载] 选择对应下载方式 上传到 /usr/local/ 目录下。 2、安装 #进入操作目录 cd /usr/local#创建安装目录 mk…

javascript常用的东西

JavaScript 是一门强大的编程语言&#xff0c;用于为网页添加交互性和动态性。也可以锻炼人们的逻辑思维&#xff0c;是一个非常好的东西。 一、变量和数据类型&#xff1a; 变量&#xff1a; 变量是用于存储数据值的容器。在 JavaScript 中&#xff0c;你可以使用 var、let…

ELK之LogStash介绍及安装配置

一、logstash简介 集中、转换和存储数据 Logstash 是免费且开放的服务器端数据处理管道&#xff0c;能够从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的“存储库”中。 Logstash 能够动态地采集、转换和传输数据&#xff0c;不受格式或复杂度的…

2023.8 - java - Java 方法

什么是方法呢&#xff1f; Java方法是语句的集合&#xff0c;它们在一起执行一个功能。 方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建&#xff0c;在其他地方被引用 方法的命名规则 1.方法的名字的第一个单词应以小写字母作为开头&#xff0…

铁威马教程丨铁威马NAS如何使用安全顾问工具

在使用NAS的过程中&#xff0c;我们时常可能忽略了一些小细节&#xff0c;久而久之可能造成一定的风险&#xff0c;影响着我们NAS的健康。而使用铁威马NAS的安全顾问工具&#xff0c;可以快速地帮我们扫描系统设置是否安全&#xff0c;让我们更放心更安心地使用NAS。 安全顾问…

【Antd】Cascader 级联组件添加顶部栏(解决低版 antd 无 dropdownRender 属性方案)

文章目录 背景实现 背景 表单级联菜单需要添加表头&#xff0c;用于表示各级含义。 如果你的antd版本大于等于4.4.0&#xff0c;则直接可以使用dropdownRender 属性自定义&#xff0c;本篇文章可以直接跳过。 参数说明类型默认值版本dropdownRender自定义下拉框内容(menus: R…

LabVIEW利用线性压缩弹簧开发重量测量系统

LabVIEW利用线性压缩弹簧开发重量测量系统 柔性传感器的曲率半径相对于指定重量的变化特性可用作力测量方法。在许多应用中&#xff0c;例如&#xff1a;汽车和工业控制&#xff0c;计算机外围设备&#xff0c;操纵杆和测量设备&#xff0c;带有压缩弹簧和柔性传感器的重量测量…

【第三阶段】kotlin语言的takeUnless内置函数

1.takeUnless和takeif功能是相反的 username.takeif{true/false} true:返回username本身 false:返回null username.takeUnless{true/false} false:返回username本身 true:返回nullpackage Stage3 class Manager{private var info:String?nullfun getInfo()infofun setI…

ROS系统API接口

文章目录 一、 节点1. 节点初始化 ros API官网链接 一、 节点 1. 节点初始化 API名称&#xff1a;ros::init() ROS程序调用的第一个函数&#xff0c;用于对ROS程序的初始化。API常用形式&#xff1a; ros::init()函数最常见的使用方式为 ros::init(argc, argv, "my_n…

C++位域

Bit field 是什么&#xff1f; “ 位域 “ 或 “ 位段 “(Bit field)为一种数据结构&#xff0c;可以把数据以位的形式紧凑的储存&#xff0c;并允许程序员对此结构的位进行操作。这种数据结构的一个好处是它可以使数据单元节省储存空间&#xff0c;当程序需要成千上万个数据单…