数据结构 - 顺序表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.hqwc.cn/news/158562.html

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

相关文章

农业中的机器学习

机器学习训练模型推荐&#xff1a; UnrealSynth虚幻合成数据生成器 - NSDT 机器学习是一个不断发展的领域&#xff0c;在农业中有许多潜在的应用。农民和农业科学家正在探索如何转向机器学习开发来提高作物产量、减少用水量和预测病虫害。未来&#xff0c;机器学习可以帮助农民…

ASTM F963-23美国玩具安全新标准发布

新标准发布 2023年10月13日&#xff0c;美国材料与试验协会&#xff08;ASTM&#xff09;发布了新版玩具安全标准ASTM F963-23。 主要更新内容 与ASTM F963-17相比&#xff0c;此次更新包括&#xff1a;单独描述了基材重金属元素的豁免情况&#xff0c;更新了邻苯二甲酸酯的管控…

Flutter GetX的使用

比较强大的状态管理框架 引入库&#xff1a; dependencies:get: ^4.6.6一.实现一个简单的demo 实现一个计数器功能 代码如下&#xff1a; import package:flutter/material.dart; import package:get/get.dart;void main() > runApp(const GetMaterialApp(home: Home()…

怎么理解电流超前电压、电压超前电流?

电容和电感&#xff0c;电压超前电流&#xff0c;电流超前电压都是我们经常听到的。作为非专业人士&#xff0c;这些听起来确实有点摸不着头脑&#xff0c;今天特别查了下电容、电感、电压电流相关资料&#xff0c;总算是弄明白了&#xff0c;在此特地记录下&#xff01; 1. 电…

【嵌入式开发学习】__软件工程师的关键原则-18个系统设计概念

目录 前言 01. 域名系统 (DNS) 02. 负载均衡器 03. API 网关 04. 内容交付网络 (CDN) 05. 正向代理与反向代理 06. 缓存 07. 数据分区 08. 数据库复制 09. 分布式消息系统 10. 微服务 11. 数据库 12. 前端缓存 13. 后端缓存 14. 安全性 15. 高可用性与容错性 …

.NET Core 中插件式开发实现

在 .NET Framework 中&#xff0c;通过AppDomain实现动态加载和卸载程序集的效果&#xff1b;但是.NET Core 仅支持单个默认应用域&#xff0c;那么在.NET Core中如何实现【插件式】开发呢&#xff1f; 一、.NET Core 中 AssemblyLoadContext的使用 1、AssemblyLoadContext简…

java数据机构.冒泡排序,选择排序 插入排序 递归算法,递归求阶乘,快速排序

排序算法 冒泡排序选择排序插入排序递归算法递归求1~100的和递归求阶乘 快速排序总结 冒泡排序 相邻两个元素比较,大的放右边,小的放左边 第一轮循环结束最大值已经找到,在数组最右边(归为算法) 第二轮在剩余的元素比较找到次大值,第二轮可以少循环一次 如果有n个数据,总共我们…

数智赋能!麒麟信安参展全球智慧城市大会

10月31日至11月2日&#xff0c;为期三天的2023全球智慧城市大会长沙在湖南国际会展中心举办&#xff0c;大会已连续举办12届&#xff0c;是目前全球规模最大、专注于城市和社会智慧化发展及转型的主题展会。长沙市委常委、常务副市长彭华松宣布开幕&#xff0c;全球智慧城市大会…

Servlet 初始化参数(web.xml和@WebServlet)

1、通过web.xml方式 <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://xmlns.jcp.org/xm…

计算机由于找不到msvcr120.dll无法执行代码的解决方法分享(亲测有效)

在使用软件过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“找不到msvcr120.dll无法继续执行代码”。这个问题通常是由于缺少Microsoft Visual C Redistributable Packages for Visual Studio 2013&#xff08;简称MSVCRT&#xff09;导致的。MSVCRT是…

AI集成ChatGPT敲代码神器Copilot

&#x1f4d1;前言 本文主要是AI工具Copilot解读文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#xff1a;努力…

Gopro hero5运动相机格式化后恢复案例

Gopro运动相机以稳定著称&#xff0c;旗下的Hero系列销售全球。下面我们来看一个Hero5格式化后拍了少量素材的恢复案例。 故障存储:64G MicroSD卡 Exfat文件系统 故障现象: 64G的卡没备份数据时做了格式化操作又拍了一条&#xff0c;发现数据没有备份&#xff0c;客户自行使…