Java ArrayLIst与顺序表

news/2024/5/18 14:41:49/文章来源:https://blog.csdn.net/weixin_44070116/article/details/128118044
  1. 什么是集合类?
    Java当中的集合类,其实就是封装号的数据结构
    原始的数据结构——>Java当中封装成的集合对应的那个原始的数据结构——>用Java封装的集合对应的。
    集合类所在的包:java.util这个包底下

  2. 顺序表的底层是一个数组,数组作为ArrayList类的成员,在这个类里面提供了对数组的增删改查等操作
    ArrayList类中方法的实现:

import java.util.Arrays;public class MyArraylist {public int[] elem; //顺序表的数组public int usedSize;//当前顺序表数组的大小是几个//默认容量private static final int DEFAULT_SIZE = 10; //常量public MyArraylist() {this.elem = new int[DEFAULT_SIZE]; //调用构造方法对数组进行初始化}/*** 打印顺序表:* 根据usedSize判断即可*/public void display() {for (int i = 0; i < this.usedSize; i++) {  //要学会使用thisSystem.out.print(this.elem[i] + " ");}System.out.println();}// 新增元素,默认在数组最后新增public void add(int data) {if(isFull()) {//扩容this.elem = Arrays.copyOf(this.elem,this.elem.length*2);}this.elem[usedSize] = data;this.usedSize++;}/*** 判断当前的顺序表是不是满的!** @return true:满   false代表空*/public boolean isFull() {if (this.usedSize == this.elem.length) {return true;}return false;//或者直接一条语句//return this.usedSize == this.elem.length;}private boolean checkPosInAdd(int pos) {if (pos >= 0 && pos <= this.usedSize) {return true;//合法}return false;}// 在 pos 位置新增元素public void add(int pos, int data) {if (!checkPosInAdd(pos)) {throw new AddIndexOutExcepetion("新增元素的位置pos不合理");}if (isFull()) {this.elem = Arrays.copyOf(this.elem,this.elem.length*2);}//移动数据for (int i = pos; i < usedSize; i++) {this.elem[i + 1] = this.elem[i];}this.elem[pos] = data;this.usedSize++;}// 判定是否包含某个元素public boolean contains(int toFind) {for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toFind) {return true;}}return false;}// 查找某个元素对应的位置public int indexOf(int toFind) {for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toFind) {return i;}}return -1;}//判断获取元素的位置是否合法public boolean checkPosInGet(int pos) {if (pos < 0 || pos >= this.usedSize) {return false;}return true;}// 获取 pos 位置的元素public int get(int pos) {if (!checkPosInGet(pos)) {throw new GetIndexOutExcepetion("查找的位置不在范围内");}if (isEmpty()) {throw new ArrayEmptyException("数组为空无法获取pos位置元素");}return this.elem[pos];}private boolean isEmpty() {if (usedSize == 0) {return true;}return false;}// 给 pos 位置的元素设为【更新为】 valuepublic void set(int pos, int value) {if (!checkPosInGet(pos)) {throw new GetIndexOutExcepetion("更新的位置不合法");}if (isEmpty()) {throw new ArrayEmptyException("数组为空");}this.elem[pos] = value;}/*** 删除第一次出现的关键字key** @param key*/public void remove(int key) {if (isEmpty()) {throw new ArrayEmptyException("顺序表为空,不能删除");}int index = indexOf(key); //调用方法获得key的下标if (index == -1) {System.out.println("没有要删除的关键字");return;}for (int j = index; j < this.usedSize; j++) {this.elem[j] = this.elem[j+1];}this.usedSize--;//        for (int i = 0; i < this.usedSize; i++) {
//            if (this.elem[i] == key) { //可通过上述完成的方法来完成
//                for (int j = i; j < this.usedSize; j++) {
//                    this.elem[j] = this.elem[j+1];
//                }
//                this.usedSize--;
//                break;
//            }
//        }}// 获取顺序表长度public int size() {return this.usedSize;}// 清空顺序表public void clear() {this.usedSize = 0;}
}

自定义异常:

public class AddIndexOutExcepetion extends RuntimeException{public AddIndexOutExcepetion() {}public AddIndexOutExcepetion(String message) {super(message);}
}public class ArrayEmptyException extends RuntimeException{public ArrayEmptyException() {}public ArrayEmptyException(String message) {super(message);}
}public class GetIndexOutExcepetion extends RuntimeException{public GetIndexOutExcepetion() {}public GetIndexOutExcepetion(String message) {super(message);}}
  1. ArrayList是一个泛型类(ArrayList的构造)
    实例化ArrayList对象的方法——主要有3种
    ①调用无参构造方法
        ArrayList<Integer> arrayList= new ArrayList<>();

分析源码:
在这里插入图片描述
用此方法实例化arraylist的对象的时候,刚开始并没有为arrayList中的元素开辟空间,此时的数组是一个空数组,即相当于elementData = {};,那么如果调用add方法添加元素的时候,就会给数组扩容了,见总结第4点。

②传入一个数值(即给定数组容量)

        ArrayList<Integer> arrayList= new ArrayList<>(10);

分析源码:
在这里插入图片描述
如果传入的数值大于0,则数组的容量就是传入的数值
如果传入的数值等于0,则给一个空数组{}
如果传入的数值小于0,则抛出异常

③参数为一个类

        LinkedList<Integer> list = new LinkedList<>();list.add(1);list.add(2);list.add(3);ArrayList<Integer> arrayList= new ArrayList<>(list);

分析源码:
在这里插入图片描述
利用其他Collection构建ArrayList,Collection<? extends E> c,把另一个实现Collection接口的类的集合拿过来作为参数,其中c的类型一定是E或者E的子类。

  1. 当调用无参构造器实例化对象的时候,此时的数组是一个空数组{},若此时调用add方法则会扩容。
    public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);}

在上述情况下,第一次调用add方法时,会给arrayList扩容,给其底层的elementData分配内存,大小为10。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:虽然一开始,代码没有分配内存,但是当第一次add的时候,会走到grow方法里分配内存大小,此时elemdata数组最后分配的大小长度是10。

  1. 遍历ArrayList的四种方法
    public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);arrayList.add(4);//方法1:toString方法System.out.println(arrayList);//方法2:for-each方法for (Integer x: arrayList) {System.out.print(x + " ");}System.out.println();//方法3:for循环+下标for (int i = 0; i < arrayList.size(); i++) {System.out.print(arrayList.get(i) + " ");}System.out.println();//方法4:迭代器Iterator<Integer> list = arrayList.iterator();while (list.hasNext()) {System.out.print(list.next() + " ");}}

分析:
①toString方法,说明重写了toString方法
但是ArrayList里面并没有重写toString,于是去寻找其父类 AbstractList,也没有重写toString方法,于是去找AbstractList的父类AbstractCollection,终于AbstractCollection中重写了toString方法,就这样被继承到了ArrayList中。
在这里插入图片描述
②for-each方法
此时arraylist里面的元素类型是Integer类型。
③for+下标
通过ArrayList中的get(i下标)的方法来遍历数组
④迭代器listIterator
迭代器是设计模式的一种
在这里插入图片描述
在这里插入图片描述

  1. ArrayList常见操作中的remove和subList方法
    ①注意E remove(int index) 与 boolean remove(Object o)的区别【方法重载】
    删除下标为index位置的元素,并且返回这个元素。
    删除元素为o的那个元素,返回值是布尔类型。
    那么 remove(1);到底是删除下标为1的那个元素,还是元素值为1的那个元素呢?
    public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.remove(1);System.out.println(list);}

运行结果:
在这里插入图片描述
分析:此时remove中的参数1识别为下标,而不是对象。那么要删除元素值为1的那个元素如何删除?

    public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.remove(new Integer(1));System.out.println(list);}

运行结果:

在这里插入图片描述
分析:list.remove(new Integer(1));,传入对象,则可以区别开。
②subList方法:返回值是List,截取部分list
LIst< E > subList(int fromIndex, int toIndex)

    public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);List<Integer> sub = list.subList(1,3);sub.set(1,999);System.out.println(sub);System.out.println(list);}

运行结果:
在这里插入图片描述
分析: sub.set(1,999);,sub和list的对应位置都变成999,这也说明虽然构成一个新的list返回,但是和ArrayList共用一个elementData数组。

  1. 运用ArrayList知识编程
    题目:s1 = “Welcome to world!” ; s2 = “come!”,去除s1中s2包含的字符,则打印输出"Wl t wrld"
    代码:
    public static void main(String[] args) {String s1 = "Welcome to world!";String s2 = "come!";ArrayList<Character> list = new ArrayList<>();for (int i = 0; i < s1.length(); i++) {//看s2中是否包含s1中的字符,所以逐一取出s1中的字符char ch = s1.charAt(i);if (!s2.contains(ch + "")) {//contains的参数是CharSequence,所以要把字符变成字符串list.add(ch);}}for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i));}}

运行结果:
在这里插入图片描述

  1. 杨辉三角(力扣118)
    分析:
    在这里插入图片描述
    代码:
class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret = new ArrayList<>();List<Integer> row1 = new ArrayList<>();row1.add(1);//第一行ret.add(row1);for(int i = 1; i < numRows; i++) {List<Integer> curRow = new ArrayList<>();//每行第一个元素curRow.add(1);List<Integer> preRow = ret.get(i - 1); //获取上一行//每行的中间元素,则要获取上一行for(int j = 1; j < i; j ++) {int x = preRow.get(j) + preRow.get(j - 1);curRow.add(x);}//每行最后一个元素curRow.add(1);ret.add(curRow);}return ret;}
}
  1. 删除排序数组中的重复项(力扣26)
    分析:
    在这里插入图片描述

代码:

class Solution {public int removeDuplicates(int[] nums) {int count = 1;for(int i = 1; i < nums.length; i++) {if(nums[i] != nums[count - 1]) {nums[count] = nums[i];count++;}}return count;}
}
  1. 简单的洗牌算法
    封装牌类
package demo4;//封装牌
public class Card {private String suit; //花色private int rank; //牌值//带参数的构造方法public Card(String suit, int rank) {this.suit = suit;this.rank = rank;}//get和set方法public String getSuit() {return suit;}public void setSuit(String suit) {this.suit = suit;}public int getRank() {return rank;}public void setRank(int rank) {this.rank = rank;}//重写toString方法,为了更好打印输出@Overridepublic String toString() {return "{" +suit + rank + "}";}
}

游戏类:(实现买牌和洗牌)

package demo4;import java.util.ArrayList;
import java.util.Random;public class Game {//牌的四种花色public static String[] suits = {"♥","♠","♦","♣"};//买一副牌public ArrayList<Card> buyCard() {ArrayList<Card> list = new ArrayList<>();for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {list.add(new Card(suits[i],j));}}return list;}//洗牌public void shuffle(ArrayList<Card> list) {Random random = new Random();for (int i = list.size() - 1; i > 0; i--) {int j = random.nextInt(i); //在当前牌之前随机取一张牌交换swap(list,i,j);}}//交换牌private void swap(ArrayList<Card> list, int i, int j) {Card tmp = list.get(i);list.set(i,list.get(j));list.set(j,tmp);}}

测试类:调用游戏类方法,并发牌

package demo4;import java.util.ArrayList;
import java.util.List;public class Test {public static void main(String[] args) {Game game = new Game();//买牌ArrayList<Card> list = game.buyCard();System.out.println(list);//洗牌game.shuffle(list);System.out.println(list);//发牌 (三个人,每个人轮流抓5张牌)//3个人,每个人手里的牌List<Card> people0 = new ArrayList<>();List<Card> people1 = new ArrayList<>();List<Card> people2 = new ArrayList<>();//具备关联关系,利用二维数组List<List<Card>> hands = new ArrayList<>();hands.add(people0);hands.add(people1);hands.add(people2);//外层:每次发5张牌for (int i = 0; i < 5; i++) {//内层,一共3个人for (int j = 0; j < 3; j++) {hands.get(j).add(list.remove(0));//每次都是揭0下标的牌,删除0下标的值,会返回0下标值对应的那张牌}}System.out.println("发牌了!");for (int i = 0; i < 3; i++) {System.out.println(hands.get(i));}}
}

运行结果:
在这里插入图片描述
对于发牌的分析:
在这里插入图片描述

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

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

相关文章

结构力学常用公式表,早晚用得到!

来源&#xff1a;360个人图书馆 常用截面几何与力学特征表​​​​​​​ 注&#xff1a; I 称为截面对主轴&#xff08;形心轴&#xff09;的截面惯性矩 (mm4)。基本计算公式如下&#xff1a; W称为截面抵抗矩 (mm)&#xff0c;它表示截面抵抗弯曲变形能力的大小&#xff0c…

皕杰报表之隐藏处理

第一步&#xff0c;新建报表&#xff0c;然后新建参数 参数type设置成中文描述为统计类型、数据类型为字符串。 参数year设置成中文描述为年、数据类型为日期、时间日期格式为yyyy。 参数month设置成中文描述为月、数据类型为日期、时间日期格式为MM。 参数day设置成中文描…

python安全工具开发笔记(三)——python 多线程

一、Python线程和进程 进程 进程是程序的一次执行。每个进程都有自己的地址空间、内存、数据栈及其它记录其运行轨迹的辅助数据。 线程 所有的线程运行在同一个进程当中&#xff0c;共享相同的运行环境。线程有开始顺序执行和结束三个部分。 帮助理解&#xff1a; 1、计算…

VM系列振弦采集模块传感器激励方法

VM系列振弦采集模块传感器激励方法 通过修改寄存器 EX_METH.[3:0]来完成激励方法的选择&#xff0c; EX_METH[4]用于设置是否忽略传感器的接入检测而强制发送激励信号。 高压脉冲激励法 高压脉冲激励法 HPM&#xff08; High Voltage Pulse Excitation Method&#xff09;。 向…

桌面画图工具:Pointofix(fertig)

Pointofix桌面画图工具 Pointofix - der virtuelle Textmarker fr Ihren Bildschirm - Freeware 一、软件下载 官方网址https://www.pointofix.de/ 二、进入下载页面&#xff0c;需要下载安装文件和语言包两个文件 三、网站还提供了一个语言设置小程序&#xff0c;但我没用 …

教师如何创建百度百科词条?这篇带你了解

互联网时代&#xff0c;如果你是小有名气的人物&#xff0c;或是某个领域的专家&#xff0c;对于社会有一定的贡献或是影响力&#xff0c;就可以在百度上搜到一个你的专属词条。 百度百科词条就是个人的一张网络名片&#xff0c;人物的一些基本信息、生平事迹、代表作品、所获…

mac下安装nodejs跟vscode

1.打开官网 Node.js 2.点击下载 3.下载完成&#xff0c;根据提示下一步安装&#xff0c;安装完成后&#xff0c;在vscode中新建一个js文件&#xff0c;执行node test.js

基于STM32单片机的篮球计时记分器proteus仿真原理图PCB

功能&#xff1a; 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示比赛剩余时间&#xff0c;球队分数 2.默认计时器为4节&#xff0c;每节10分钟&#xff0c;每节比赛结束&#xff0c;蜂鸣器报警 3.按键功能介绍: 1’键——加1分 4’键——减1分 2’键——加2分 5’键—…

[附源码]计算机毕业设计springboot人体健康管理app

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

静态路由配置案例

静态路由配置案例配置静态路由原理命令&#xff1a;案例&#xff1a;最后结果&#xff1a;配置静态路由原理命令&#xff1a; [Huawei]ip route-static 来源ip 子网掩码 去向ip [Huawei]ip route-static 192.168.20.1 255.255.255.0 192.168.1.2 案例&#xff1a; pc1,pc2,a…

MySQL数据库实现主从复制,docker实现版

我这里是在同一台电脑上使用docker实现的主从复制&#xff0c;在物理机上整体思路是一致的 预备工作&#xff1a;安装好docker 使用docker运行MySQL 拉取MySQL镜像 docker pull mysql:5.7运行mysql master容器 sudo docker run -p 33061:3306 --name mysql-master-v /myda…

Docker with IPV6

1、绪论 在 Docker 容器或群服务中使用 IPv6 之前&#xff0c;您需要在 Docker 守护进程中启用 IPv6 支持。之后&#xff0c;您可以选择对任何容器、服务或网络使用 IPv4 或 IPv6&#xff08;或两者&#xff09; 2、配置默认 Docker IPv6 注意&#xff1a;IPv6 网络仅在 Lin…

揭秘你代理商做不起来货卖不出去的原因,探讨其背后的商业逻辑

现在很多代理商&#xff0c;大都是可以归于“个体户”性质。这些也代表了微小型企业&#xff0c;从前期的蓬勃发展&#xff0c;到现在的经营受限&#xff0c;特别是疫情等影响&#xff0c;很多人的经营都处于举步维艰的状态&#xff0c;如果你们现在是代理商&#xff0c;仓库里…

【Ubuntu】修改ubuntu和windows双系统启动顺序

目录一、问题描述二、背景知识1. GRUB是什么2. GRUB配置文件3./etc/default/grub 主配置文件二、问题分析三、解决方案1. 修改grub主配置文件2. 更新grub配置文件一、问题描述 UbuntuWindows双系统默认使用GRUB作为引导管理器&#xff0c;而且通常默认启动Ubuntu。这样过于死板…

CrossOver2023虚拟机软件安装双系统教程

您喜欢切换Windows系统吗&#xff1f;喜欢&#xff1f;好吧&#xff0c;您随意。对于其他人而言&#xff0c;想要不依赖于笨重的 Windows 模拟器就能在您的 Mac 系统上运行微软的应用程序&#xff0c;CrossOver是最简单的方式。讲真&#xff0c;您试过模拟器了吗&#xff1f;您…

美信监控易:网络管理之链路专线管理

专线通常是指运营商为企事业单位提供的专用网络线路&#xff0c;用于满足其业务需求。专线管理可以提供对专线基础信息的维护&#xff0c;以及性能数据的监测能力。通过系统自动地、周期性地执行专线测试&#xff0c;获取指标数据&#xff0c;实现专线连通性、性能数据的全面感…

DDD的简单落地实现

目录 概述 和微服务的联系 具体划分 遵循依赖倒置原则 其他规范 具体实现代码 总结 概述 领域式驱动&#xff08;DDD&#xff09; 这种模式的核心就是根据功能去划分领域&#xff0c;然后在这个领域内只做这个领域的事情。 和微服务的联系 和微服务有什么类似的地方&am…

[附源码]Python计算机毕业设计Django高校车辆管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

浅浅的计算机网络知识

目录 计算机网络&#xff08;连接分散计算机设备以实现信息传递的系统&#xff09;_百度百科 传输协议 传输层次 通信 计算机网络协议分层结构 开放系统互连参考模型的特点 IPv4协议 IPv6协议 FTP HTTP 网络传输协议 较为系统框架 先面向百度搭建理解框架 计算机网…

【OpenCV-Python】教程:3-10 直方图(4)直方图反向投影

OpenCV Python 直方图 反向投影 【目标】 直方图反向投影calcBackProject 【原理】 用于图像分割和查找感兴趣目标。简单的说&#xff0c;会创建一个与输入图像同样大小的图像&#xff08;单通道&#xff09;&#xff0c;每个像素对应像素属于目标的概率。更简单的说就是&am…