数据结构 - ArrayList - 动态修改的数组

目录

实现一个通用的顺序表

总结

包装类

装箱 / 装包 和 拆箱 / 拆包

ArrayList 与 顺序表

ArrayList基础功能演示

add 和 addAll ,添加元素功能

ArrayList的扩容机制

来看一下,下面的代码是否存在缺陷

模拟实现 ArrayList

add 功能

add index 

add 两种用法的效果图

remove 功能 - 删除删除遇到的第一个 指定元素

remove 功能 - 删除 index 位置元素

get - 获取指定下标位置元素

set - 将指定的下标的元素,置换为 指定的数据

clear - 清空

contains - 判断 指定元素 是否在线性表中

indexOf 和 lastIndexOf ,直接搬原码(注意indexOf 是前面写了的(只要把private改成public就行),直接搬lastIndexOf)

总结:

ArrayList 实践案例 - 扑克牌

发牌 / 揭牌


实现一个通用的顺序表

顺序表的功能不是重点,我们在这里只是粗略实现一下顺序表的功能,重点在泛型

准备工作,相信大家都看得懂。

class MyArrayList{private int[] elem;// 建立数组private int usedSize;// 有效元素个数// 构造方法public  MyArrayList(){this.elem = new int[10];// 默认数组初始容量为 10}// 添加元素public void add(int val){this.elem[usedSize] = val;}// 得到指定位置的元素public int get(int pos){return  this.elem[pos];}
}
public class Test {
}

但是这个代码并不通用,只能存储一种数据类型(int)。

总结

1. 泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。
2. 泛型代码在运行期间,就是我们上面提到的,利用 Object 达到的效果(这里不是很准确,以后会做说明)。
3. 泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。
4. 泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。
5. 泛型是一种编译期间的机制,即 MyArrayList 和 MyArrayList 在运行期间是一个类型。
6. 泛型是 java 中的一种合法语法,标志就是尖括号 <>


包装类

Object 引用可以指向任意类型的对象,但有例外出现了,8 种基本数据类型不是对象,那岂不是刚才的泛型机制要
失效了?

实际上也确实如此,为了解决这个问题,java 引入了一类特殊的类,即这 8 种基本数据类型的包装类,在使用过程
中,会将类似 int 这样的值包装到一个对象中去。

基本数据类型和包装类直接的对应关系

基本就是类型的首字母大写,除了 Integer 和 Character

包装类存在的意义

当我们需要将某种类型的数据转换成其它的数据类型时,需要通过某种来达到目的。
而包装类就是这些功能的集大成者,包含多种类型转换方法和其他功能。


实战(讲一个字符串类型转换成整形数据)


装箱 / 装包 和 拆箱 / 拆包

装箱 / 装包 :就是把简单类型数据 变为 包装类类型数据
拆箱 / 拆包 : 就是把包装类类型数据 变为 简单类型数据

面试题


ArrayList 与 顺序表

铺垫

1. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
2. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
3. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的(序列化:把一个对象转换成字符串)
4. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
CopyOnWriteArrayList
5. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表 


在使用任何一个 idea编译器写好的类的时候,一定要先去看一下这个类的构造方法


ArrayList的三种打印方式


迭代器打印


ArrayList基础功能演示

add 和 addAll ,添加元素功能

public class TestDemo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("a");list.add("b");list.add("c");// 添加List元素System.out.println(list);System.out.println("===============");list.add(1,"g");// 在List指定位置中添加元素System.out.println(list);System.out.println("========");List<String> list1 = new ArrayList<>();list1.add("x");list1.add("y");list.addAll(list1);// 将一个list1 整体添加 list中System.out.println(list);}
}

remove - 删除 

1、指定下标的元素,返回值为删除元素

内部实现


2、输出从左往右 第一个指定数据 - 返回值为布尔类型

内部实现

get - 获取

获取指定下标位置的元素

内部实现

set - 赋值

- 将指定下标元素设置为指定数据(可以理解为更新指定下标元素)

- 返回值为旧元素

内部实现

clear - 清空

- 清空顺序表中的元素

- 无返回值

内部实现

contains - 判断 

- 判断 指定数据 是否在线性表中

- 返回值为布尔类型

内部实现

indexOf  

- 返回指定数据在线性表中第一次出现的位置,所对应的下标

内部实现

lastIndexOf 

- 返回 在线性表中,最后一个 与指定元素相等 的 元素下标

内部实现

subList - 截取部分

- 截取部分线性表数据 - 返回值 为 List < E > 类型

内部实现

ArrayList的扩容机制

来看一下,下面的代码是否存在缺陷

public static void main(String[] args) {List<Integer> list = new ArrayList<>();for (int i = 0; i < 100; i++) {list.add(i);}
}

首先我们认为这个代码是没有缺陷的,但是因为ArrayList 底层的数组是有一定大小的,那么存放数组的过程中,一定会涉及到扩容,

前面我们讲到ArrayList 有三种方法,现在使用的是不带参数的,也就是说ArrayList 底层的数组初始容量为零。 那么第一个问题就出现了: 既然数组的容量是为零,那么它怎么还可以存入数据?

第二个问题: 假设数组初始化容量为10,超过了10,就需要扩容。而且扩容操作时在代码底层执行,是看不见的,也就是说ArrayList在存储数据,隐式的进行扩容操作,那么它的扩容机制是怎样的?

模拟实现 ArrayList

新建一个 MyArrayList 类


构造方法:带参 和 不带参的 两个构造方法

先来看不带参的

带参的构造方法

实现它的基础功能

add 功能

add index 

add 两种用法的效果图

remove 功能 - 删除删除遇到的第一个 指定元素

remove 功能 - 删除 index 位置元素

get - 获取指定下标位置元素

set - 将指定的下标的元素,置换为 指定的数据

clear - 清空

contains - 判断 指定元素 是否在线性表中

indexOf 和 lastIndexOf ,直接搬原码(注意indexOf 是前面写了的(只要把private改成public就行),直接搬lastIndexOf)

总结:

基本功能都实现了,除了subList 没有实现,到后面写到。
另外 你有没有发现。其实你想要模拟顺序表的功能实现,最好的老师就是原码。以后大家在学习某一个数据结构时,先看它的原码,它会帮助你理解并掌握。

ArrayList 实践案例 - 扑克牌

目的:
        1.构造一副扑克牌

        2.洗牌
        3.揭牌

扑克牌的特点:

        1.点数(13点)
        2.花色(四种花色)

注意:我们这副扑克,不包含大小王。

发牌 / 揭牌

import java.util.ArrayList;
import java.util.List;
import java.util.Random;class Card{private int point;private String flowerColor;public Card(int point, String flowerColor) {this.point = point;this.flowerColor = flowerColor;}public int getPoint() {return point;}public void setPoint(int point) {this.point = point;}public String getFlowerColor() {return flowerColor;}public void setFlowerColor(String flowerColor) {this.flowerColor = flowerColor;}@Overridepublic String toString() {return "{  " +flowerColor +" "+point+" }";}
}public class PlayingCard {// 定义 扑克牌的花色private static final String[] flowerColors = {"♥","♠","♦","♣"};// 创建一副扑克public  static List<Card> newCard() {ArrayList<Card> cards = new ArrayList<>();for (int i = 0; i < 4; i++) {// 4种花色for (int j = 1; j <= 13; j++) {// 尖 到 k 一共13个点数cards.add(new Card(j,flowerColors[i]));}}return cards;}// 洗牌public static void shuffle(List<Card> list){// 牌数是52,数组下标就是51// 从最后一张牌开始,随机与 本身 或者 本身前面的任意一张牌 交换位置。// 这样的做交换性 比 从开头洗  的 打乱顺序的 效率 高。for (int i = list.size()-1; i >0 ; i--) {// Random 是一个生成随机数的类Random random = new Random();// 通过 Random的引用 random 去调用 nextInt() 方法。// random.nextInt() 方法,根据括号中的值,随机生成 0 ~ 括号中的值int rand = random.nextInt(i);// 将 第 i 张牌 , 与 自身 或者 自身前面的任意一张牌的下标 丢给 swap方法// 让它去交换位置swap(list,i,rand);}}// 交互式洗牌模式private static void swap(List<Card> list,int i,int j){// 我们现在是面向对象,ArrayList虽然底层是一个数组,但是需要使用方法,才能操作数组的元素// 并不能像数组一样,直接操作// Card tmp = list[i];Card tmp = list.get(i);// 获取 顺序表中,对应下标的元素// list[i] = list[j];list.set(i,list.get(j));// 将 j下标的元素,赋给 i 下标的元素,// list[j] = tmp;list.set(j,tmp);}public static void main(String[] args) {System.out.println("======一副买来拆的牌==========");List<Card> list = newCard();System.out.println(list);System.out.println("======== 洗牌 =========");shuffle(list);System.out.println(list);System.out.println("======== 发牌,3个人轮着发,每个人5张牌=========");ArrayList<ArrayList<Card>> player = new ArrayList<>();// 这行代码 就是 一个二维数组,// 首先我们有一个player, player 的每个元素 都是 ArrayList<Card> 类型。// 也就是说每个元素就是一个顺序表,也可以说是一个一维数组。// 你也可以这么理解 第一个 ArrayList 是用来记录有 玩家的方位/顺序表的地址/数组的地址// 第二个ArrayList 就是 每个玩家手上牌的情况/数组的元素情况/顺序表的底层数组元素情况。//  你可以 把 player 看作牌桌,等待三位玩家的入场。// 打牌三人组ArrayList<Card> playerOne = new ArrayList<>();ArrayList<Card> playerTwo = new ArrayList<>();ArrayList<Card> playerThree = new ArrayList<>();// 将三位玩家的信息,加载到 player 当中player.add(playerOne);player.add(playerTwo);player.add(playerThree);for (int i = 0; i < 5; i++) {// 发 5 轮牌for (int j = 0; j < 3; j++) {// 每个人 轮着发,最终每个人5张牌Card card = list.remove(0);player.get(j).add(card);}}// 打印每个人的手牌System.out.println("playerOne的手牌:"+ playerOne);System.out.println("playerTwo的手牌:"+playerTwo);System.out.println("playerThree的手牌:"+playerThree);System.out.println("list 剩余的牌:"+list);}//    public static void main1(String[] args) {
//        Card card = new Card(3,"♠");
//        System.out.println(card);
//    }
}

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

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

相关文章

什么是 DevOps

DevOps是一套融合软件开发&#xff08;Dev&#xff09;和 IT 运营&#xff08;Ops&#xff09;的实践&#xff0c;旨在缩短应用程序开发周期并确保以高软件质量持续交付&#xff0c;通过采用 DevOps 实践&#xff0c;您可以帮助组织更可靠、更快速、更高效地交付软件。 什么是…

SLAM从入门到精通(计算点到直线的距离)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 大家一开始看到这个题目的时候&#xff0c;也许比较吃惊。为什么会有这样的题目&#xff1f;但是做过slam的同学&#xff0c;应该就比较熟悉和了解…

Echats-自定义图表1

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh-cmn-Hans"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…

uniapp生命周期

uniapp生命周期包括应用生命周期、页面生命周期和组件生命周期&#xff1b; 1、应用生命周期 app.vue/uvue是uni-app的朱组件。所有页面都是在app.vue下进行切换&#xff0c;是应用入口文件。但app.vue本身不是页面&#xff0c;这里补鞥编写视图元素&#xff0c;也就没有。 这…

vue生命周期

1、vue声明周期及生命周期函数 vue声明周期 每一个vue实例从创建到销毁的过程&#xff0c;就是这个vue实例的生命周期。在这个过程中&#xff0c;他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程&#xff1b; 生命周期&#xff1a;…

唇形驱动媲美头部厂商,青否数字人SaaS系统6.0重磅发布!

青否数字人SaaS系统6.0重磅发布&#xff01;唇形驱动效果及清晰度媲美硅基等头部厂商&#xff0c;同时优化数字人短视频模块。 唇形驱动媲美头部 青否数字人SaaS系统6.0版本重点优化了唇形驱动&#xff0c;AI技术已经实现与真人形象的1:1克隆&#xff0c;唇形、牙齿和舌头高清…

当科技遇上神器:用Streamlit定制AI可视化问答界面

Streamlit是一个开源的Python库&#xff0c;利用Streamlit可以快速构建机器学习应用的用户界面。 本文主要探讨如何使用Streamlit构建大模型外部知识检索的AI问答可视化界面。 我们先构建了外部知识检索接口&#xff0c;然后让大模型根据检索返回的结果作为上下文来回答问题。…

【AUTOSAR】【以太网】DoIp

AUTOSAR专栏——总目录_嵌入式知行合一的博客-CSDN博客文章浏览阅读217次。本文主要汇总该专栏文章,以方便各位读者阅读。https://xianfan.blog.csdn.net/article/details/132072415 目录 一、概述 二、功能描述 2.1 Do

DNS 域名解析协议

作用 将域名转化位IP地址 域名 用’ . ’ 隔开的字符串&#xff0c;如&#xff1a;www.badu.com,就是为了赋予IP特殊含义。 一级域名 .com &#xff1a;公用 .cn&#xff1a;中国 .gov&#xff1a;政府 .us&#xff1a;美国 .org&#xff1a;组织 .net&#xff1a;网站 对应一级…

HTML脚本、字符实体、URL

HTML脚本&#xff1a; JavaScript 使 HTML 页面具有更强的动态和交互性。 <script> 标签用于定义客户端脚本&#xff0c;比如 JavaScript。<script> 元素既可包含脚本语句&#xff0c;也可通过 src 属性指向外部脚本文件。 JavaScript 最常用于图片操作、表单验…

Vue路由导航(replace、push、forward、back、go)

Vue路由导航&#xff08;replace、push、forward、back、go&#xff09; 先了解栈结构&#xff0c;再学习以下内容 栈的数据结构&#xff1a;先进后出&#xff0c;后进先出。原理&#xff1a;push将元素压入栈内&#xff0c;pop将元素弹出&#xff0c;栈有分别有栈底指针和栈顶…

C++11 initializer_list 轻量级初始化列表的使用场景(让自定义类可以用初始化列表的形式来实例化对象)

initializer_list 是 C11 中的一个特性&#xff0c;它允许你使用花括号 {} 中的值列表来初始化容器或数组。通常用于初始化标准库容器&#xff0c;比如 std::vector、std::set、std::map 以及数组。 场景一&#xff1a;用初始化列表初始化容器 std::vector<int> arr {…

Java中Deque栈对象的增删查(所有方法详解)

1、Deque栈的增删查方法总结 2、方法增删查 栈顶添加&#xff1a;push、offFirst栈尾添加&#xff1a;add、offer、offerLast栈顶删除&#xff1a;remove、pop、poll、pollFirst栈尾删除&#xff1a;pollLast栈顶查看&#xff1a;peek、peekFirst栈尾查看&#xff1a;peekLast…

搭载基于RK3229的Android5.1修改开机默认桌面Launcher

1、找到ActivityManagerService.java 在..\rk3229_5.1_box\frameworks\base\services\core\java\com\android\server\am目录找到ActivityManagerService.java文件。在文件里找到startHomeActivityLocked函数里的setDefaultLauncher。 boolean startHomeActivityLocked(int use…

软件设计模式原则(一)迪米特法则

开一个小专题——详细总结一下软件设计模式原则&#xff0c;这部分在《软计》和《java设计模式》中算是很重要的知识点&#xff0c;值得展开详细讲解一下~首先介绍的是【迪米特法则】 一.定义 迪米特法则又称为最少知识原则&#xff0c;其定义为&#xff1a;一个软件实体应当尽…

微众银行备用金怎么取出来

在这个数字时代里&#xff0c;互联网金融产品以其便捷性和创新性逐渐成为我们日常生活中不可或缺的一部分。微众银行作为国内领先的互联网银行&#xff0c;其旗下的微众备用金产品凭借其灵活、便捷的特性&#xff0c;深受消费者喜爱。那么&#xff0c;微众备用金怎么借钱出来呢…

JavaScript中BOM与DOM

BOM window对象 所有的浏览器都支持window对象&#xff0c;他表示浏览器窗口&#xff0c; 所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。 全局变量是 window 对象的属性。全局函数是 window 对象的方法。 接下来要讲的HTML DOM 的 document 也是…

【设计模式】第24节:行为型模式之“模板方法模式”

一、简介 模板方法模式在一个方法中定义一个算法骨架&#xff0c;并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下&#xff0c;重新定义算法中的某些步骤。 模板模式有两大作用&#xff1a;复用和扩展。其中&#xff0c;复用指的是&#…

Tailwind CSS vs 现代CSS,Tailwind CSS 会像CSS-in-JS 一样亡?

本文是 关于Tailwind CSS 与 现代 CSS之间比较的文章。文章中作者详细比较了这两种CSS开发方法的优缺点。他指出&#xff0c;Tailwind CSS是一种基于类的CSS框架&#xff0c;提供了快速开发网站的便利性&#xff0c;但可能导致HTML代码的臃肿。另一方面&#xff0c;现代CSS方法…

蓝桥杯每日一题2023.10.31

题目描述 全球变暖 - 蓝桥云课 (lanqiao.cn) 题目分析 果然有关连通块类的问题使用dfs都较为好写~~ 我们可以通过判断连通块的代码来加上部分条件算出被完全淹没的岛屿个数 在岛屿中如果有为"#"的a[i][j]上下左右全部是"#"则说明此岛屿一定不会被完全…