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

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

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

相关文章

机器学习基础(二)

线性回归 误差是独立并且具有相同的分布通常认为服从均值为0方差为的高斯分布。 损失函数(loss Function)/代价函数(Cost Function) 其实两种叫法都可以,损失函数(loss function)或代价函数(cost function)是将随机事件或其有关随机变量的取值映射为非负实数以表示该随…

Android开发之性能优化:过渡绘制解决方案

1. 过渡绘制 屏幕上某一像素点在一帧中被重复绘制多次&#xff0c;就是过渡绘制。 下图中多个卡片跌在一起&#xff0c;但是只有第一个卡片是完全可见的。背后的卡片只有部分可见。但是Android系统在绘制时会将下层的卡片进行绘制&#xff0c;接着再将上层的卡片进行绘制。但其…

springcloud3 hystrix实现服务降级的案例配置2

一 服务降级的说明 1.1 服务降级说明 "服务器忙&#xff0c;请稍后在试"不让客户达等待&#xff0c;立即返回一个友好的提示。 1.2 服务降级的触发情况 1.程序运行异常&#xff1b; 2.超时&#xff1b; 3.服务熔断触发服务降级&#xff1b;4 .线程池/信号量打…

电商增强现实3D模型优化需要关注的4个方面

到目前为止&#xff0c;AR技术已经发展到足以在更广泛的范围内实施。 在电子商务中&#xff0c;这项技术有望提供更令人兴奋的购物体验。 为了实现这一目标&#xff0c;在这篇博客中&#xff0c;我将介绍如何针对电子商务中的 AR 优化 3D 模型。 推荐&#xff1a;用 NSDT编辑器…

Python 函数

Built-in Functions — Python 3.11.4 documentation

Transformer(二)(VIT,TNT)(基于视觉CV)

目录 1.视觉中的Attention 2.VIT框架&#xff08;图像分类&#xff0c;不需要decoder&#xff09; 2.1整体框架 2.2.CNN和Transformer遇到的问题 2.3.1CNN 2.3.2Transformer 2.3.3二者对比 2.4.公式理解 3TNT 参考文献 1.视觉中的Attention 对于人类而言看到一幅图可以立…

区块链系统探索之路:私钥的压缩和WIF格式详解

在前面章节中&#xff0c;我们详细介绍了公钥的压缩&#xff0c;在比特币网络中&#xff0c;一个私钥可以对应两个地址&#xff0c;一个地址是由未压缩公钥所生成的地址&#xff0c;另一个就是由压缩公钥所创建的地址&#xff0c;从公钥到区块链地址的转换算法&#xff0c;我们…

【设计模式——学习笔记】23种设计模式——解释器模式Interpreter(原理讲解+应用场景介绍+案例介绍+Java代码实现)

案例引入 通过解释器模式来实现四则运算&#xff0c;如计算ab-c的值&#xff0c;具体要求 先输入表达式的形式&#xff0c;比如abc-de&#xff0c;要求表达式的字母不能重复在分别输入a,b,c,d,e的值最后求出结果 传统方案 编写一个方法&#xff0c;接收表达式的形式&#xf…

基于Pan-Tompkins的实时QRS检测算法:便携式ANSI-C实现深入解析

引言 随着医学工程和移动设备技术的进步&#xff0c;实时QRS检测算法在心电图分析中变得越来越重要。其中&#xff0c;Pan-Tompkins算法由于其高效性和准确度&#xff0c;在许多应用中都受到广泛认可。本文将深入探讨此算法的ANSI-C实现&#xff0c;并提供详细的代码实例。 1…

【kubernetes】配置资源管理

目录 Secret 创建 Secret 1、用kubectl create secret命令创建Secret 2、内容用 base64 编码&#xff0c;创建Secret 使用方式 1、将 Secret 挂载到 Volume 中&#xff0c;以 Volume 的形式挂载到 Pod 的某个目录下 2、将 Secret 导出到环境变量中 ConfigMap 创建 Co…

请解释一下CSS中的rem和em单位有什么不同,分别如何使用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS中的rem和em单位的区别和使用⭐ em单位使用示例&#xff1a; ⭐ rem 单位使用示例&#xff1a; ⭐ 区别和适用场景⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何…

Nginx常见的三个漏洞

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

[英语单词] compat; compatibility;compact;entry_SYSENTER_compat

简介 这个词compat&#xff0c;马上就会被简写形式所替代。所以一定不要和compact混淆。第一次看到还以为是个新词来&#xff0c;后来发现是一个缩写形式。就是兼容的意思&#xff0c;就如同兼容以往的就有事物。 syscall: 32bit: 兼容 entry_SYSENTER_compat 这个是32位程序…

MySQL存储过程 、存储函数、以及优缺点

存储过程 VS 存储函数&#xff08;函数&#xff09; | | 关键字 |调用语法 | 返回值 | 应用场景 | |-存储过程-|-procedure-|-call 存储过程()-|-理解为0个或多个-|-一般用于更新-| | 存储函数 | function | select 函数() | 只能是一个 | 一般用于查询结构为一个值并返回时| …

三、python Django ORM postgresql[数据定时备份、数据恢复]

一、数据定时备份 解释&#xff1a;备份指定数据库&#xff0c;能有效在发生错误时&#xff0c;预防错误&#xff0c;进行恢复 1.基本备份 #!/bin/bash sudo -u postgres pg_dump -U postgres -d dbname -Fc > /home/postgres/backup/backup.dump # sudo -u postgres&…

讯飞星火、文心一言和通义千问同时编“贪吃蛇”游戏,谁会胜出?

同时向讯飞星火、文心一言和通义千问三个国产AI模型提个相同的问题&#xff1a; “python 写一个贪吃蛇的游戏代码” 看哪一家AI写的程序直接能用&#xff0c;谁就胜出&#xff01; 讯飞星火 讯飞星火给出的代码&#xff1a; import pygame import sys import random# 初…

Android 13 开启关闭飞行模式

一.背景 由于客户定制的Settings里面需要开启和关闭飞行模式,所以需要实现此功能。 二.前提条件 首先应用肯定要是系统应用,并且导入framework.jar包,具体可以参考: Android 应用自动开启辅助(无障碍)功能并使用辅助(无障碍)功能_android 自动开启无障碍服务_龚礼鹏的博客…

步入React正殿 - React组件设计模式

目录 扩展学习资料 高阶组件 /src/components/hoc/withTooltip.js /src/components/hoc/itemA.jsx /src/components/hoc/itemB.jsx /src/App.js 函数作为子组件【Render pprops】 函数作为子组件 /src/components/rp/itemC.jsx【父组件】 /src/components/rp/withToo…

C#调用C++ DLL传参byte[]数组字节值大于127时会变为0x3f的问题解决

最近做了一个网络编程的DLL给C#调用&#xff0c;DLL中封装了一个TCP Client的函数接口&#xff0c;如下所示 //C TCP报文发送接口 int TcpClient_send(unsigned char* buffSend, unsigned int nLen) {unsigned char buff[1024];int len StringToHex(buffSend, buff);int nRet…

stable diffusion安装包和超火使用文档,数字人制作网址

一&#xff1a;文生图、图生图 1&#xff1a;stable diffusion&#xff1a;对喜欢二次元、美女小姐姐、大眼萌妹的人及其友好哈哈(o^^o) 1&#xff09;&#xff1a;秋叶大神安装包和模型包&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/11_kguofh76gwhTBPUipepw 提…