数据结构-ArrayList

news2024/11/14 3:55:19

目录

线性表

顺序表

ArrayList

ArrayList的使用

ArrayList的构造方法

ArrayList的常用方法

ArrayList的遍历

实现简单的ArrayList

洗牌算法

删除公共字符串问题

杨辉三角


线性表

线性表是n个具有相同特性的数据元素的有限序列.线性表是一种在实际中广泛使用的数据结构.常见的线性表有顺序表,链表,栈和队列等等.

线性表在逻辑上是线性结构,也就是说是连续的一条直线.但是在物理结构上并不一定是连续的,线性表在物理上存储的时候,通常是以数组和链式结构的形式存储.

顺序表

顺序表是一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下用数组存储.在数组上完成数据的增删查改.

ArrayList

在集合框架中,ArrayList是一个普通的类,实现了List接口.

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

ArrayList的使用

ArrayList的构造方法

 第二种构造方法,实现了collection接口的都可以传进来.但是需要注意的是E是泛型通配符的上界,只有类型相同是E或者是E的子类的时候,才可以传进来.

当我们调用不带参数的构造方法的时候,只有第一个add的时候,我们才会为其分配大小为10的内存.

扩容是采用1.5倍的扩容方式.如果用户所需大小超过预估的1.5倍大小,则按照用户所需大小进行扩容,并且在真正的扩容之前会检测能否扩容成功,防止太大导致扩容失败.扩容是采用copyOf进行扩容.


ArrayList的常用方法

subList方法需要注意的是:截取的部分并没有创建新的顺序表,而是新的引用(截取的部分)还是指向了原来的顺序表.所以修改截取部分的内容就是将原来顺序表的内容给修改了.

对于remove需要注意的是,编译器会将我们传入的int类型的值统一认定为是下标而不是实际内容的值.

比如有一个ArrayList:[1,7]两个元素.

public static void main(String[] args) {
    ArrayList<Integer> arrayList = new ArrayList<>();
    arrayList.add(1);
    arrayList.add(7);
    System.out.println(arrayList);
    //我们要删除值为7的元素
    //arrayList.remove(7);//编译器会把7当成下标,而不是实际的值,所以我们执行起来会报越界错.
    //正确的做法是传入一个引用类型
    arrayList.remove(new Integer(7));
}

ArrayList的遍历

ArrayList的遍历有三种:for循环+下标的方式,foreach,和迭代器.

public static void main(String[] args) {
    ArrayList<Integer> arrayList = new ArrayList<>();
    arrayList.add(1);
    arrayList.add(2);
    arrayList.add(3);
    arrayList.add(4);
    //for循环+下标
    for (int i = 0; i < arrayList.size(); i++) {
        System.out.printf(arrayList.get(i)+" ");
    }
    System.out.println();
    //foreach
    for (int x:arrayList) {
        System.out.printf(x+" ");
    }
    System.out.println();
    //使用迭代器
    //必须实现了Iterable接口
    Iterator<Integer> it = arrayList.iterator();
    while (it.hasNext()){
        //it指向上一个数据
        //it.next()会使it访问下一个元素并且向下走一步
        System.out.printf(it.next()+" ");
    }
    System.out.println();
}

实现简单的ArrayList

import java.util.Arrays;

public class MyArrayList {
    public int[] elem;//数组
    public int usedSize;//记录有效的数据的个数
    public static final int DEFAULT_SIZE = 10;

    public MyArrayList(){
        this.elem = new int[DEFAULT_SIZE];
    }

    // 打印顺序表
    public void display() {
        for (int i = 0;i < this.usedSize; i++){
            System.out.print(this.elem[i]+" ");
        }
        System.out.println();
    }
    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //1.检查当前的顺序表是不是满了
        if (isFull()){
            //2.如果满了就要扩容
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        //3.
        this.elem[usedSize] = data;
        //4.
        usedSize++;
    }

    public boolean isFull(){
        if (this.usedSize > elem.length){
            return true;
        }
        return false;
    }

    // 在 pos 位置新增元素
    //负数下标不可以
    //越过数组的长度不可以
    //不能隔着元素放
    public void add(int pos, int data) throws PosWrongfulException {
        if (isFull()){
            System.out.println("满了!");
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        if (pos < 0 || pos > this.usedSize){
            System.out.println("pos的位置不合法!");
            throw new PosWrongfulException("Pos位置不合法!");
        }

        //pos一定是合法的
        //1.开始挪动数据
        for (int i = this.usedSize-1; i >= pos; i--) {
            this.elem[i+1] = this.elem[i];
        }
        //2.插入数据
        this.elem[pos] = data;
        //3.usedSize++
        usedSize++;
    }
    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if (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;
    }
    // 获取 pos 位置的元素
    public int get(int pos) {
        //判空
        if (isEmpty()){
            throw new EmptyException("当前顺序表为空!");
        }
        //判断pos位置的合法性
        if (pos < 0 || pos >= this.usedSize){
            throw new PosWrongfulException("get获取元素的时候,Pos位置不合法!");
        }
        return this.elem[pos];
    }
    //判空
    public boolean isEmpty(){
        return size() == 0;
    }
    // 给 pos 位置的元素更新为 value
    public void set(int pos, int value) {
        //判空
        if (isEmpty()){
            throw new EmptyException("当前顺序表为空!");
        }
        //判断pos位置的合法性
        if (pos < 0 || pos >= this.usedSize){
            throw new PosWrongfulException("pos位置不合法!");
        }
        this.elem[pos] = value;
    }
    //删除第一次出现的关键字key
    public void remove(int key) {
        if (isEmpty()){
            throw new EmptyException("顺序表为空!");
        }
        int index = this.indexOf(key);
        if (index == -1){
            System.out.println("没有这个数字!");
            return;
        }
        // 9 3 4 8 6
        // 0 1 2 3 4
        //usedSize==5,i<4,i最大到3
        //index==4的情况下直接不走循环,usedSize--即可.
        for (int i = index; i <size()-1 ; i++) {
            this.elem[i] = this.elem[i+1];
        }
        usedSize--;
    }
    // 获取顺序表长度
    public int size() { return this.usedSize; }
    // 清空顺序表
    public void clear() {
        this.usedSize = 0;
    }

}

洗牌算法

使用ArrayList实现三个人轮流摸牌的过程.

1.先买一副扑克牌,四种花色,每种花色13张.

2.洗牌

3.揭牌,每人按序摸一张,总共摸五轮.

public class Poker {
    //花色
    private String suit;
    //数值
    private int rank;

    public Poker(String suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public void setSuit(String suit) {
        this.suit = suit;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public String getSuit() {
        return suit;
    }

    public int getRank() {
        return rank;
    }

    @Override
    public String toString() {
        return "["+"suit= " + suit + ", rank=" + rank +"]";
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;



//1.买一副扑克牌
//2.洗牌
//3.三个人轮流揭牌,每个人揭5次
public class Pokers {
    public static final String[] SUITS = {"♥","♠","♣","♦"};

    /**
     *买一副扑克牌
     */

    public static List<Poker> bugPokers(){
        List<Poker> pokerList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 13; j++) {
                String suit = SUITS[i];
                int rank = j;
                Poker poker = new Poker(suit,rank);
                pokerList.add(poker);
            }
        }
        return pokerList;
    }
    //洗牌
    public static void shuffle(List<Poker> list){
        Random random = new Random();
        for (int i = list.size()-1; i > 0 ; i--) {
            int index = random.nextInt(i);
            swap(list,i,index);
        }
    }

    private static void swap(List<Poker> list, int i, int index) {
        Poker tmp = list.get(i);
        list.set(i,list.get(index));
        list.set(index,tmp);
    }

    public static void main(String[] args) {
        List<Poker> list = bugPokers();
        System.out.println("买牌:"+list);
        //洗牌
        shuffle(list);
        System.out.println("洗牌:"+list);
        //揭牌 3个人 每个人轮流抓五张牌
        //1.如何描述3个人
        List<Poker> hand1 = new ArrayList<>();
        List<Poker> hand2 = new ArrayList<>();
        List<Poker> hand3 = new ArrayList<>();
        //2.如何区分往哪个人手里送牌
        List<List<Poker>> hand = new ArrayList<>();
        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 3; j++) {
                List<Poker> handTmp = hand.get(j);
                handTmp.add(list.remove(0));
            }
        }
        for (int i = 0; i < hand.size(); i++) {
            System.out.println("第"+(i+1)+"个人的牌是:"+hand.get(i));
        }
        System.out.println("剩余的牌是: "+ list);
    }
}

删除公共字符串问题

//删除第一个字符串当中出现的第二个字符串中的字符,使用集合
//str1:welcome to bit
//str2:come
//输出wel t bit
//需要注意的是contains方法传的是一个字符串,字符+""就是将字符传为字符串,也可以字符包装类的toString方法将一个字符转为字符串
public static void main(String[] args) {
    String s1 = "welcome to bit";
    String s2 = "come";
    ArrayList<Character> arrayList = new ArrayList<>();
    for (int i = 0; i < s1.length(); i++) {
        if (!s2.contains(s1.charAt(i)+"")){
            arrayList.add(s1.charAt(i));
        }
    }
    for (Character a:arrayList) {
        System.out.printf(a.toString());
    }
}

杨辉三角

public List<List<Integer>> generate(int numRows) {
    List<List<Integer>> ret = new ArrayList<>();
    List<Integer> list1 = new ArrayList<>();
    list1.add(1);
    ret.add(list1);
    for (int i = 1; i <numRows ; i++) {
        //当前行
        List<Integer> curRow = new ArrayList<>();
        curRow.add(1);//一行中开始的1
        //前一行
        List<Integer> prevRow = ret.get(i-1);
        //中间位置需要计算
        for (int j = 1; j < i; j++) {
            int num = prevRow.get(j)+prevRow.get(j-1);
            curRow.add(j,num);
        }
        curRow.add(1);//一行中最后的那个1
        ret.add(curRow);
    }
    return ret;
}

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

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

相关文章

【标准】国家标准GB7713-87(科学论文编写格式)

目 录 1 引言 2 定义 2.1 科学技术报告 2.2 学位论文 2.3 学术论文 3 编写要求 4 编写格式 5 前置部分 5.1 封面 5.2 封二 5.3 题名页 5.4 变异本 5.5 题名 5.6 序或前言 5.7 摘要 5.8 关键词 5.9 目次页 6 主体部分 6.1 格式 6.2 序号 6.3 引言(或绪论)…

如何在没有软件的情况下将 PDF 转换为 PPT(100% 免费)

演示文稿由文字、图片、音频、动画等元素组成&#xff0c;通常用于会议、课堂或演讲中&#xff0c;展示演讲者想要表达的主要内容。如果您遇到重要文档以 PDF 格式存储&#xff0c;但现在需要转换为 PPT 格式的情况&#xff0c;请不要担心。我们本指南的目标是帮助用户将 PDF 转…

BeanFactory和ApplicationContext的入门、关系和继承

BeanFactory快速入门 ApplicationContext快速入门 BeanFactory与ApplicationContext的关系 1)BeanFactory是Spring的早期接口&#xff0c;称为Spring的Bean工厂。ApplicationContext是后期更高级接口&#xff0c;称之为Spring 容器; 2)ApplicationContext在BeanFactory基础上…

路径规划算法:基于瞬态优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于瞬态优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于瞬态优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法瞬态…

充电桩系统的阿里云服务器的配置如何?

两台ecs. 微信公众号 微信小程序 微信商户 Redis mysql netty mqtt 更多信息私信我

【Leetcode】203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val0, nextNone): # self.val va…

Apollo、RocketMQ加载顺序问题

在SpringCloudAlibaba框架中&#xff0c;因Nacos配置中心管理权限过于简单&#xff0c;决定用Apollo代替Nacos配置中心&#xff0c;但在启动时&#xff0c;Nacos、Redis等配置读取正常&#xff0c;RocketMQ由于启动过早&#xff0c;无法从Apollo读取自己的服务地址配置。 报错…

基于github制作个人学术网站(主页)

模板 首先找到一个学术模板&#xff0c;fork到远程仓库。academicpages&#xff0c;如果不是很清楚具体的步骤&#xff0c;可以参考保姆级教程。在github上对该网站代码修改不是很方便&#xff0c;肯定是在本地进行更新后push到远程仓库。 本地Git 学会下载和安装就行&#…

读取摄像机的内参和畸变系数并对畸变图像进行去畸变

这个程序的目标是读取摄像机的参数(内参和畸变系数),并对畸变图像进行去畸变操作,然后进行一些特征点和矩形框的绘制。 #include 语句引入所需的库。using namespace std; 和 using namespace cv; 语句是在代码中使用std和opencv命名空间,这样就不用在每次使用这些库的函数…

Bluetooth 开发科普

Bluetooth 开发科普 1、蓝牙协议结构 Controller运行在蓝牙芯片上&#xff0c;host运行在主控上&#xff0c;两芯片通过硬件通信接口&#xff08;uart或usb&#xff09;&#xff0c;进行通信连接&#xff08;HCI&#xff09;。 实际使用中有不同场景&#xff0c;根据场景需求&…

第三章 SSD存储介质:闪存 3.2-3.3

3.2 闪存实战指南 闪存接口有同步异步之分。一般来说&#xff0c;异步传输速率慢&#xff0c;同步传输速率快。 &#xff08;1&#xff09;异步接口没有时钟&#xff0c;每个数据读由一次RE_n信号触发&#xff0c;每个数据写由一次WE_n信号触发。 &#xff08;2&#xff09;同步…

又曝新作!阿里P9再出山,操作性超强的Spring源码实践

如果你看懂了 Spring 源码&#xff0c;再去看 MyBatis、Spring Security 源码&#xff0c;你会发现这些源码都非常容易&#xff0c;稍微瞅几眼就懂了。 然而源码的学习是一个枯燥的过程&#xff0c;源码解读也是一个枯燥的过程&#xff0c;但是一旦你把源码搞懂了&#xff0c;…

远程接口调用工具Feign

JAVA 项目中如何实现接口调用&#xff1f; Httpclient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带的 U…

C++、QT(GUI)知识库系统

目录 一、项目介绍 二、项目展示 三、源码分享 一、项目介绍 知识库系统 为一些常用知识进行统一储存、管理、更新、检索等功能的系统&#xff0c;整体类似于博客之类的系统。 用户的使用流程&#xff1a; 查看知识&#xff1a;搜索知识关键字 -> 点击查看知识内容 -…

Simulink仿真模块 - Delay

Delay:按固定或可变采样期间延迟输入信号 在仿真库中的位置为:Simulink / Commonly Used Blocks Simulink / Discrete HDL Coder / Commonly Used Blocks HDL Coder / Discrete 模型为: 双击模型打开参数设置界面,如图所示: 说明 Delay 模块会在一段延迟之后再输出模块的…

FreeRTOS ~(五)队列的常规使用 ~ (5/5)队列集

举例子说明&#xff1a;队列集的使用 队列集&#xff1a;Queue Set 多个队列的集合,一个队列中依次存放多个队列的句柄一般使用API的流程如下: 1.创建几个队列 2.创建队列集 3.把这几个队列添加进队列集中 然后可以创建任务去使用队列和队列集static QueueHandle_t xQueu…

[MySQL]可重复读下的幻读

一、幻读的定义 根据MySQL官网的描述&#xff0c;幻读是“相同的查询在不同时间返回了不同的结果” The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. 同时官网还举例说明了&#xff0c;如…

图形学 | 期末复习(上)| games101笔记 | 补档

博客基于GAMES101-现代计算机图形学入门-闫令琪&#xff0c;但不是其完整笔记&#xff0c;基于复习要求有一定的删减。考试以图形学入门基本概念和核心研究内容为主&#xff0c;少量公式。即以论述概念为主&#xff0c;涉及少量算法。p1:29:12是对应的games101视频节点&#xf…

maven在vscode添加依赖操作

1.maven查找依赖 点击进入网站&#xff0c;搜索需要的依赖包名选择一个合适的依赖 根据自己需要选择版本 选中maven&#xff0c;复制好代码&#xff0c;粘贴到pom.xml 2. 添加新的依赖 在pom.xml文件中&#xff0c;添加了依赖后&#xff0c;打开vscode终端&#xff0c;输入以…

matlab解微分方程

1.匿名函数 1.1创建 f(变量) 表达式; f(x1,x2) x1.^2x2;1.2 求解 x1为2 3 4 5&#xff1b;x2为3 4 5 6的情况下求解函数f的值 f(x1,x2) x1.^2x2; yf(2:5,3:6); subplot(121);%选择子图位置 plot(y)%画图2.一阶微分方程 用“dsolve” 2.1例 y.-y0 step1: 申明自变量和因…