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

news2024/11/27 16:46:51

目录

实现一个通用的顺序表

总结

包装类

装箱 / 装包 和 拆箱 / 拆包

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;
    }

    @Override
    public 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.coloradmin.cn/o/1166821.html

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

相关文章

Linux安装配置awscli命令行接口工具及其从aws上传下载数据

官网技术文档有全面介绍&#xff1a;安装或更新 AWS CLI 的最新版本 - AWS Command Line Interface在系统上安装 AWS CLI。https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/getting-started-install.html#getting-started-install-instructionsawscli常用命令参考&…

红海云签约澳森集团,为钢铁行业人力资源数字化转型注入新动能

辛集市澳森特钢集团有限公司&#xff08;以下简称“澳森集团”&#xff09;是集钢铁冶炼、轧钢及钢材深加工、新型建材、国际贸易、房地产开发、酒店餐饮、热力供应于一体的大型钢铁联合企业&#xff0c;是华北地区最具品牌影响力和核心竞争力的综合性大型企业集团。 近日&…

LBS营销|基于位置信息的营销策略

LBS营销&#xff08;Location-Based Services Marketing&#xff09;是一种基于位置信息的营销策略&#xff0c;它利用移动设备和位置数据来为消费者提供与其当前位置相关的个性化信息和服务。LBS营销通过分析用户的地理位置&#xff0c;向他们提供特定地点或地理区域的有关信息…

虚拟数字人技术篇

1. 虚拟数字人概念解析 虚拟数字人它是由三个部分组成:虚拟、数字、人。 虚拟:存在于非物理世界,多模态存在于各种介质;数字:数字化,可复制多个分身,多技术综合体;人:具备拟人化的外表和行为交互的能力。具体说明如下: 虚拟: 通常是指它是存在于非物理世界,可以是…

基于生成对抗网络的照片上色动态算法设计与实现 - 深度学习 opencv python 计算机竞赛

文章目录 1 前言1 课题背景2 GAN(生成对抗网络)2.1 简介2.2 基本原理 3 DeOldify 框架4 First Order Motion Model5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于生成对抗网络的照片上色动态算法设计与实现 该项目较为新颖&am…

Docker安装matomo

Docker安装matomo 文章目录 Docker安装matomo1.安装Docker2.matomo安装 1.安装Docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun2.matomo安装 #拉取matomo镜像 docker pull matomo#启动matomo容器 docker run -d --name matomo -p 8093:80 -v /do…

喜讯!苏州箱讯获评苏州市软件和信息服务业 “头雁”培育企业

近日&#xff0c;由中国电子信息产业发展研究院、中国工业经济联合会、国家智能制造专家委员会、国家产业基础专家委员会、江苏省工业和信息化厅、江苏省国有资产监督管理委员会、苏州市人民政府共同主办的2023第三届中控中国大会在苏州太湖国际会议中心举办。 本届大会以“生态…

erp 技术的发展趋势和方向有哪些?

近日&#xff0c;亿欧智库重磅发布了《2022中国制造业ERP研究报告》。亿欧通过桌面研究及行业专家访谈&#xff0c;对ERP在制造业领域的应用情况进行分析&#xff0c;洞察ERP针对制造业不同场景的服务模式&#xff0c;研讨制造业ERP的未来发展趋势&#xff0c;旨在帮助制造业企…

OPCUA 行业配套标准:机器人

OPC UA 定义了对象&#xff0c;对象类型&#xff0c;结构化组织能力和定义对象之间关系的能力&#xff0c;利用这些基础和衍生类型及对象&#xff0c;用户还可以搭建出更复杂的类型&#xff0c;关系和对象。 如果不同的厂商或者用户定义的信息模型不同&#xff0c;将会影响系统…

springboot+vue基于JAVA的企业内部人员绩效量化管理系统的设计与实现【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

时间复杂度的计算技巧-算法模型中的时间复杂度如何计算,有哪些技巧呢

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下时间复杂度的计算技巧-算法模型中的时间复杂度如何计算&#xff0c;有哪些技巧呢&#xff0c;算法的时间复杂度是评估算法性能和效率的一种方式&#xff0c;它表示算法需要执行多少次基本操作才能完成其任务&#x…

【数据库】关系数据库管理系统 (RDBMS) 中事务处理的四个特性ACID

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 数据库事务是指一组数据库操作&#xff08;例如插入、更新、删除等&#xff09;&#xff0c;被视为一个单独的逻辑操作单元&#xff0c;并且要么全部执行成功&#xff0c;要么全部不执行&…

Eolink Apikit 如何对所有 API 异常请求实时监控 ?

API 监控适合业务在互联网上&#xff0c;并且用户来自多个不同的地区&#xff0c;且对API的要求较高的场合&#xff0c;用于解决以下的问题&#xff1a; 发现由于网络中断或者是API响应异常等导致的服务不可用 及时对异常的API进行告警 记录监控的日志&#xff0c;方便排查 …

基于Jaccard相似度的推荐算法---示例

目录 数据展示推荐算法的分类基于相似度基于流行度/上下文/社交网络 Jaccard相似度分析数据的特点可以考虑的方法计算方法优缺点计算用户之间的Jaccard相似度获取与给定最相似的10个用户对1713353的用户推荐10本书 数据展示 import pandas as pd import numpy as np# 读取CSV文…

vue+elementUI 设置el-descriptions固定长度并对齐

问题描述 对于elementUI组件&#xff0c;el-descriptions 在以类似列表的形式排列的时候&#xff0c;上下无法对齐的问题。 问题解决 在el-descriptions 标签中&#xff0c;添加属性&#xff1a; :contentStyle"content_style" 控制其内容栏长度 <el-descripti…

Visual Components Robotics OLP解决方案 北京衡祖

Visual Components 引入了“Visual Components Robotics OLP”的重大升级&#xff0c;合并了制造模拟和机器人离线编程。该解决方案利用 Delfoi Robotics 的技术&#xff0c;提高生产率、减少停机时间并减少浪费。 一、探索下一代离线机器人编程软件 自 1999 年以来&#xff0…

强大的pdf编辑软件:Acrobat Pro DC 2023中文

Acrobat Pro DC 2023是一款强大的PDF编辑和管理软件&#xff0c;它提供了广泛的功能&#xff0c;使用户能够轻松创建、编辑、转换和共享PDF文档。通过直观的界面和先进的工具&#xff0c;用户可以快速进行文本编辑、图像调整、页面管理等操作&#xff0c;同时支持OCR技术&#…

MobPush自定义智能标签,赋能精细化运营

随着用户兴趣爱好日益多元化&#xff0c;如何精准把握用户喜好&#xff0c;向用户定制推送用户所喜好的内容&#xff0c;成为APP能否提升用户粘性和活跃度&#xff0c;形成竞争力的关键。 因此&#xff0c;MobPush此前全面上新了”智能标签“功能&#xff0c;成为无数APP运营者…

图形化ping工具gping

一、介绍 gping能够以折线图的方式&#xff0c;实时展示 ping 的结果&#xff0c;支持 Windows、Linux 和 macOS 操作系统。并且支持多个目标同时Ping同时展示折线图方便对比。下面扩展一下ICMP及ICMP隧道。 ICMP消息结构&#xff1a; ICMP消息是由一个类型字段、一个代码字段、…

数据结构——顺序表(SeqList)

目录 1. 顺序表介绍 2. 顺序表工程 2.1 顺序表定义 2.1.1 静态顺序表 2.1.2 动态顺序表 2.2顺序表接口 2.2.1 顺序表初始化 2.2.2 顺序表打印 2.2.3 顺序表销毁 2.2.4 顺序表数据插入 2.2.4.1 容量检查 2.2.4.2 顺序表尾插 2.2.4.3 顺序表头插 2.2.4.4 顺序表随机…