当前位置: 首页 > news >正文

【数据结构】 ArrayList简介与实战

文章目录

  • 什么是ArrayList
    • ArrayList相关说明
  • ArrayList使用
    • ArrayList的构造
      • 无参构造
      • 指定顺序表初始容量
      • 利用其他 Collection 构建 ArrayList
      • ArrayList常见操作
        • 获取list有效元素个数
        • 获取和设置index位置上的元素
        • 在list的index位置插入指定元素
        • 删除指定元素
        • 删除list中index位置上的元素
        • 检测list中是否包含指定元素
        • 查找指定元素第一次出现的位置
        • 截取部分 list
    • ArrayList的遍历
      • for循环+下标
      • foreach
      • 使用迭代器
      • 注意事项
    • ArrayList的扩容机制
      • 小结
  • ArrayList的具体使用
    • 杨辉三角
      • 题目描述
      • 题目解释:
      • 解法思路:
      • 代码实现:
    • 简单的洗牌算法
      • Card类
      • 买牌(初始化)
      • 洗牌
      • 摸牌
      • 效果展示:
      • 完整代码:
  • 总结

什么是ArrayList

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下
在这里插入图片描述

ArrayList相关说明

  1. ArrayList是以泛型方式实现的,使用时必须要先实例化

  2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问

  3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的

  4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的

  5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList

  6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

ArrayList使用

ArrayList的构造

ArrayList的构造有三种
在这里插入图片描述

无参构造

ArrayList创建,推荐写法

// 构造一个空的列表
List<Integer> list1 = new ArrayList<>();

指定顺序表初始容量

// 构造一个具有10个容量的列表
List<Integer> list2 = new ArrayList<>(10);
list2.add(1);
list2.add(2);
list2.add(3);

利用其他 Collection 构建 ArrayList

// list3构造好之后,与list2中的元素一致
ArrayList<Integer> list3 = new ArrayList<>(list2);

ArrayList常见操作

ArrayList虽然提供的方法比较多,但是常用方法如下所示
在这里插入图片描述
例如我们有以下代码

List<String> list = new ArrayList<>();
list.add("JavaSE");
list.add("JavaWeb");
list.add("JavaEE");
list.add("遇事问春风乄");
list.add("数据结构");

获取list有效元素个数

// 获取list中有效元素个数
System.out.println(list.size());

获取和设置index位置上的元素

注意:index必须介于[0, size)间

System.out.println(list.get(1));//获取
list.set(1, "JavaWEB");//设置

在list的index位置插入指定元素

在list的index位置插入指定元素后,index及后续的元素统一往后搬移一个位置

list.add(1, "Java数据结构");

删除指定元素

删除指定元素,找到了就删除,该元素之后的元素统一往前搬移一个位置

list.remove("JavaEE")

删除list中index位置上的元素

注意:index不要超过list中有效元素个数,否则会抛出下标越界异常

list.remove(list.size()-1)

检测list中是否包含指定元素

包含返回true,否则返回false

if(list.contains("遇事问春风乄")){list.add("遇事问春风乄");
}

查找指定元素第一次出现的位置

indexOf从前往后找,lastIndexOf从后往前找

//从前往后
System.out.println(list.indexOf("JavaSE"));
//从后往前
System.out.println(list.lastIndexOf("JavaSE"));

截取部分 list

使用list中[0, 4)之间的元素构成一个新的SubList返回,但是和ArrayList共用一个elementData数组

List<String> ret = list.subList(0, 4);

ArrayList的遍历

ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器

for循环+下标

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// 使用下标+for遍历
for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " ");
}

foreach

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// 借助foreach遍历
for (Integer integer : list) {System.out.print(integer + " ");
}

使用迭代器

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
Iterator<Integer> it = list.listIterator();
while(it.hasNext()){System.out.print(it.next() + " ");
}

注意事项

  1. ArrayList最长使用的遍历方式是:for循环+下标 以及 foreach
  2. 迭代器是设计模式的一种

ArrayList的扩容机制

ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。

以下是ArrayList源码中扩容方式

 Object[] elementData; // 存放元素的空间private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默认空间private static final int DEFAULT_CAPACITY = 10; // 默认容量大小public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}private void ensureExplicitCapacity(int minCapacity) {modCount++;
// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;private void grow(int minCapacity) {
// 获取旧空间大小int oldCapacity = elementData.length;
// 预计按照1.5倍方式扩容int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果用户需要扩容大小 超过 原空间1.5倍,按照用户所需大小扩容if (newCapacity - minCapacity < 0)newCapacity = minCapacity;
// 如果需要扩容大小超过MAX_ARRAY_SIZE,重新计算容量大小if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);
// 调用copyOf扩容elementData = Arrays.copyOf(elementData, newCapacity);}private static int hugeCapacity(int minCapacity) {
// 如果minCapacity小于0,抛出OutOfMemoryError异常if (minCapacity < 0)throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;}

小结

  1. 检测是否真正需要扩容,如果是调用grow准备扩容

  2. 预估需要库容的大小
    初步预估按照1.5倍大小扩容
    如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容
    真正扩容之前检测是否能扩容成功,防止太大导致扩容失败

  3. 使用copyOf进行扩容

ArrayList的具体使用

杨辉三角

题目描述

给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在这里插入图片描述

在这里插入图片描述

题目解释:

题中返回值为 List<List< Integer > >,意思为返回一个List,这个List里面的每一个元素也为List

解法思路:

List里面放List可以类似与我们的二维数组,而我们的杨辉三角也可以看成一个二维数组

比如我们现在有一个List实例为ret,ret里面存放的是List类型的元素;ret的每一个List元素里存放的是杨辉三角每一行的所有元素
在这里插入图片描述
通过观察我们发现,杨辉三角的第一位总是1,并且每一行的最后一个与第一个都为1;其余的等于上面一行的两个数相加
在这里插入图片描述

代码实现:

class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret = new ArrayList<>();List<Integer> row = new ArrayList<>();ret.add(row);row.add(1);for(int i = 1;i < numRows;i++) {List<Integer> row1 = ret.get(i-1);List<Integer> row2 = new ArrayList<>(i);ret.add(row2);row2.add(1);for(int j = 1;j < i;j++){int h = row1.get(j) + row1.get(j-1);row2.add(h);}row2.add(1);}return ret;}
}

简单的洗牌算法

在这里插入图片描述
比如我们现在需要实现一个简单的炸金花

Card类

那么我们首先第一步,我们得了解一下扑克,我们除开大小王,就剩下52张牌。每张牌都有相应的面额和花色
在这里插入图片描述
那么我们便可以建立一个Card类用于描述我们的扑克

class Card {public int rank; // 牌面值public String suit; // 花色@Overridepublic String toString() {return String.format("[%s %d]", suit, rank);}
}

买牌(初始化)

接下来我们需要买一副牌,其实也就是对我们的牌进行初始化

一共四个花色,每一种花色对应13张牌

public static final String[] SUITS = {"♠", "♥", "♣", "♦"};// 买一副牌private static List<Card> buyDeck() {List<Card> deck = new ArrayList<>(52);for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {String suit = SUITS[i];int rank = j;Card card = new Card();card.rank = rank;card.suit = suit;deck.add(card);}}return deck;}

洗牌

买回来的牌肯定不能直接完,所以我们要进行洗牌

在洗牌环节我们会对一张张牌进行遍历,然后让该牌于随机的一张牌进行交换

这里为了随机数产生方便,我们选择从后往前遍历

private static void swap(List<Card> deck, int i, int j) {Card t = deck.get(i);deck.set(i, deck.get(j));deck.set(j, t);}private static void shuffle(List<Card> deck) {Random random = new Random();//随机数for (int i = deck.size() - 1; i > 0; i--) {int r = random.nextInt(i);swap(deck, i, r);}}

摸牌

三个人轮流摸牌,我闷这里采用二维数组的思想来实现,也就是List里面的元素是List

摸一张牌,排队里就少一张牌,这里操作起来非常简单,我们只需要将牌堆deck的0下标进行删除就好

使用E remove(int index)删除当前下标的元素,并返回该元素,将该元素添加到每一位玩家的手中

List<List<Card>> hands = new ArrayList<>();hands.add(new ArrayList<>());hands.add(new ArrayList<>());hands.add(new ArrayList<>());for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {hands.get(j).add(deck.remove(0));}}

效果展示:

在这里插入图片描述

完整代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;class Card {public int rank; // 牌面值public String suit; // 花色@Overridepublic String toString() {return String.format("[%s %d]", suit, rank);}
}public class CardDemo {public static final String[] SUITS = {"♠", "♥", "♣", "♦"};// 买一副牌private static List<Card> buyDeck() {List<Card> deck = new ArrayList<>(52);for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {String suit = SUITS[i];int rank = j;Card card = new Card();card.rank = rank;card.suit = suit;deck.add(card);}}return deck;}private static void swap(List<Card> deck, int i, int j) {Card t = deck.get(i);deck.set(i, deck.get(j));deck.set(j, t);}private static void shuffle(List<Card> deck) {Random random = new Random();for (int i = deck.size() - 1; i > 0; i--) {int r = random.nextInt(i);swap(deck, i, r);}}public static void main(String[] args) {List<Card> deck = buyDeck();System.out.println("刚买回来的牌:");System.out.println(deck);shuffle(deck);System.out.println("洗过的牌:");System.out.println(deck);
// 三个人,每个人轮流抓 5 张牌List<List<Card>> hands = new ArrayList<>();hands.add(new ArrayList<>());hands.add(new ArrayList<>());hands.add(new ArrayList<>());for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {hands.get(j).add(deck.remove(0));}}System.out.println("剩余的牌:");System.out.println(deck);System.out.println("A 手中的牌:");System.out.println(hands.get(0));System.out.println("B 手中的牌:");System.out.println(hands.get(1));System.out.println("C 手中的牌:");System.out.println(hands.get(2));}
}

总结

关于《【数据结构】 ArrayList简介与实战》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

相关文章:

【数据结构】 ArrayList简介与实战

文章目录 什么是ArrayListArrayList相关说明 ArrayList使用ArrayList的构造无参构造指定顺序表初始容量利用其他 Collection 构建 ArrayListArrayList常见操作获取list有效元素个数获取和设置index位置上的元素在list的index位置插入指定元素删除指定元素删除list中index位置上…...

您的网站不应该只提供一套通用 API

后端应该提供两套 API&#xff0c;一套是外部使用的通用 API&#xff0c;服务特定的数据&#xff0c;另一套是自家使用的应用 API&#xff0c;服务特定的页面。 在当今的web开发中&#xff0c;构建一个提供JSON服务的后端和一个渲染应用程序的前端是很流行的。我不太喜欢&…...

vue tree禁用和多选变为单选

禁用的话和后台协调一下&#xff0c;参数中多返回一个disabled 多选变单选 在tree结构中加入一个方法 <el-treeaccordion:data"deptOptions":props"defaultProps"show-checkbox:expand-on-click-node"false":filter-node-method"filte…...

ES6新特性。对象、数组新增方法

ES6新特性 ES6&#xff08;ECMAScript 2015&#xff09;是 JavaScript 的一个重要版本&#xff0c;引入了许多新的语法和功能&#xff0c;增强了语言的表达能力和开发体验。以下是 ES6 中一些重要的新特性的全面总结&#xff1a; let 和 const 声明&#xff1a; let 和 const …...

request发送http请求

今天正式开始为大家介绍接口自动化&#xff0c;相信很多做测试的朋友&#xff0c;都用过一些工具&#xff0c;比如jmeter&#xff0c;loadrunner&#xff0c;postman等等&#xff0c;所以今天先给那些基础不太好的同学&#xff0c;先讲讲postman如何来测接口以及如何用pthon代码…...

leaflet实现MARK指向的方向随机

效果图&#xff1a; npm install leaflet-rotatedmarkerL.marker([48.8631169, 2.3708919], {rotationAngle: Math.random() * 180, // 旋转角度&#xff0c;以度为单位&#xff0c;顺时针方向。rotationOrigin: "center center", // 旋转中心 }).addTo(map);...

如何使用Python编写小游戏?

大家好&#xff0c;我是沐尘而生&#xff0c;如果你是一个热爱编程的小伙伴&#xff0c;又想尝试游戏开发&#xff0c;那么这篇文章一定能满足你的好奇心。不废话&#xff0c;让我们马上进入Python游戏开发的精彩世界吧&#xff01; Python游戏开发的魅力 编写小游戏不仅仅是锻…...

【Leetcode】84.柱状图中最大的矩形(Hard)

一、题目 1、题目描述 给定 n n n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例1: 输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10示例2:…...

Arraylist集合

保存数据会经常使用到数组&#xff0c;但数组存在以下几个缺陷: 长度固定&#xff1b;保存的必须为同一类型的元素&#xff0c;&#xff08;基本数据类型&#xff0c;或引用数据类型&#xff09;&#xff1b;使用数组进行增加元素的步骤比较麻烦&#xff1b; 这个时候就需要用一…...

https的原理和方案

文章目录 https原理为什么要加密常见的加密方式对称加密非对称加密数据摘要&&数据指纹数据签名 https的几种工作方案方案一&#xff1a;只使用对称加密方案二&#xff1a;只使用非对称加密方案三&#xff1a;两端都使用非对称加密方案四&#xff1a;非对称加密 对称加…...

VTK 判断一个 点 是否在一个模型 stl 内部 vtk 点是否在内部 表面 寻找最近点

判断 一个点 ,判断是否在风格 stl 模型内部&#xff0c;或表面&#xff1a; 目录 1.方案一&#xff1a;使用vtkCellLocator FindClosestPoint 找到模型上距离给定点最近的一点&#xff0c;计算两点的距离 &#xff0c;小于某一阈值 则认为此点在模型上&#xff1b; 2.方案二…...

【数据结构OJ题】链表的回文结构

原题链接&#xff1a;https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId49&&tqId29370&rp1&ru/activity/oj&qru/ta/2016test/question-ranking 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 在做这道…...

Nginx常见的三个漏洞

目录 $uri导致的CRLF注入漏洞 两种常见场景 表示uri的三个变量 案例 目录穿越漏洞 案例 Http Header被覆盖的问题 案例 $uri导致的CRLF注入漏洞 两种常见场景 用户访问http://example.com/aabbcc&#xff0c;自动跳转到https://example.com/aabbcc 用户访问http://exa…...

爬虫逆向实战(十六)--某建筑市场平台

一、数据接口分析 主页地址&#xff1a;某建筑市场平台 1、抓包 通过抓包可以发现数据接口是list 2、判断是否有加密参数 请求参数是否加密&#xff1f; 无请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 通过查看“响应”模块可以发现&#xff0c;返回的响应是…...

用Python做一个滑雪小游戏

游戏是让人娱乐和放松的好方式&#xff0c;而编写和玩自己的游戏则是一种特别有趣的体验。在本文中&#xff0c;我们将使用Python和pygame库来创建一个简单的滑雪小游戏。通过这个小游戏项目&#xff0c;我们将学习如何使用Python编程语言来制作自己的游戏&#xff0c;并且享受…...

EXCEL按列查找,最终返回该列所需查询序列所对应的值,VLOOKUP函数

EXCEL按列查找&#xff0c;最终返回该列所需查询序列所对应的值 示例&#xff1a;国标行业分类汉字&#xff0c;匹配id 使用VLOOKUP函数 第一参数&#xff1a;拿去查询的值。 第二参数&#xff1a;匹配的数据。 Ps&#xff1a;Sheet1!$C 21 : 21: 21:E 117 &#xff0c;需要…...

java编译报错,get方法报错

java编译报错&#xff0c;get方法报错 处理方式&#xff1a; 在空间中&#xff0c;将 buid 文件夹删除 再不行的话&#xff0c;重启电脑&#xff0c;删除各种缓存 试试...

可以降低CPU负载的网络传输技术——LSO

LSO 是个啥&#xff1f; Large Send Offload&#xff08;LSO&#xff09;是一种网络传输协议技术&#xff0c;旨在提高网络传输的性能和效率。它通过将大型数据包拆分成小型数据包&#xff0c;降低网络传输负载&#xff0c;提高传输速度。 在传统的网络传输协议中&#xff0c…...

[管理与领导-25]:IT基层管理者 - 团队管理 - 如何留人, 如何留住关键人才

目录 一、离职前的五大信号&#xff0c;你读懂了吗&#xff1f; 二、员工为什么会离职 三、如何留住关键人才 一、离职前的五大信号&#xff0c;你读懂了吗&#xff1f; 离职前的信号是指员工可能在准备离职之前表现出的一些迹象或行为。 这些信号可以帮助雇主或同事们察觉…...

【Redis】Redis 的学习教程(二)之 Jedis

仅仅知道 Redis 服务端的操作知识&#xff0c;还是远远不够的&#xff0c;如果想要真正在项目中得到应用&#xff0c;我们还需要一个 Redis 的客户端&#xff0c;然后将其集成到项目中&#xff0c;让程序自动根据我们的业务需要自动处理。 基于 Redis 开放的通信协议&#xff…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...