Java ArrayLIst与顺序表

news2024/11/27 8:39:15
  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++) {  //要学会使用this
            System.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 位置的元素设为【更新为】 value
    public 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方法,为了更好打印输出


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

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

相关文章

Flutter状态管理

前言 状态管理是什么&#xff1f;简单的来说&#xff0c;就是当某个状态发生变化的时候&#xff0c;告知该状态的监听者&#xff0c;让状态所监听的属性随之而改变&#xff0c;达到UI层随着数据层变化而变化的效果。在Flutter中的状态(State)是一个组件的UI数据模型&#xff0…

【MySQL 读写分离】Sharding JDBC + Spring boot 实现数据库读写分离的登录 Demo

上篇文章我们搭建了 MySQL 数据库主从复制集群 MySQL 搭建主从复制集群~~~ 本篇文章我们利用搭建好的主从复制集群&#xff0c;使用 SpringBoot 结合 Sharding-JDBC 搭建一个小的 登录 Demo&#xff0c;测试实现数据库的读写分离 项目源码地址&#xff1a; https://gitee.com/l…

13 【操作mysql数据库】

13 【操作mysql数据库】 1.mysql 介绍 付费的商用数据库&#xff1a; Oracle&#xff0c;典型的高富帅&#xff1b;SQL Server&#xff0c;微软自家产品&#xff0c;Windows定制专款&#xff1b;DB2&#xff0c;IBM的产品&#xff0c;听起来挺高端&#xff1b;Sybase&#x…

android WebRtc 视频通话(P2P)

概述 WebRTC名称源自网页实时通信(Web Real-Time Communication)的缩写&#xff0c;是一个支持网页浏览器进行实时语音对话或视频对话的技术&#xff0c;是谷歌2010年以6820万美元收购Global IP Solutions公司而获得的一项技术。Google于2011年6月3日开源的即时通讯项目&#x…

centos7中mysql5.7.32服务离线升级到5.7.39教程

目录 一、导入新的离线安装包 二、备份原有mysql数据库 1、停止tomcat服务 2、查看mysql服务 3、备份数据库 三、停止mysql服务并打包备份旧版本 1、停止mysql 2、打包旧的mysql文件夹 3、删除旧的mysql文件夹 4、删除/etc/init.d/下跟mysql有关的全部文件&#xff0…

MongoDB数据迁移之迁移工具Kettle

MongoDB数据迁移之迁移工具Kettle ETL:简介 ETL&#xff08;Extract-Transform-Load的缩写&#xff0c;即数据抽取、转换、装载的过程&#xff09;&#xff0c;对于企业或行业应用来说&#xff0c;我们经常会遇到各种数据的处理&#xff0c;转换&#xff0c;迁移&#xff0c;所…

Java+JSP+MySQL基于SSM的医院挂号就诊系统-计算机毕业设计

项目介绍 随着计算机科技的快速发展&#xff0c;很多地方都实现了自动化管理&#xff0c;医院也不例外。在大多数医院&#xff0c;无论是挂号处&#xff0c;还是取药的窗口&#xff0c;都会看到有很长的队伍&#xff0c;很显然这样会让患者就医的过程中浪费太多的时间。其次&a…

【读论文】GANMcC

GANMcC简单介绍网络结构生成器辨别器损失函数生成器损失函数辨别器tips总结参考论文&#xff1a;https://ieeexplore.ieee.org/document/9274337 如有侵权请联系博主 这几天又读了一篇关于GAN实现红外融合的论文&#xff0c;不出意外&#xff0c;还是FusionGAN作者团队的人写…

Python语音合成小工具(PyQt5 + pyttsx3)

TTS简介 TTS&#xff08;Text To Speech&#xff09;是一种语音合成技术&#xff0c;可以让机器将输入文本以语音的方式播放出来&#xff0c;实现机器说话的效果。 TTS分成语音处理及语音合成&#xff0c;先由机器识别输入的文字&#xff0c;再根据语音库进行语音合成。现在有…

JavaScript -- 三种循环语句的介绍及示例代码

文章目录循环语句1 While循环2 do-while循环3 for循环4 嵌套循环循环语句 通过循环语句可以使指定的代码反复执行 JS中一共有三种循环语句 while语句do-while语句for语句 通常编写一个循环&#xff0c;要有三个要件 初始化表达式&#xff08;初始化变量&#xff09;条件表…

风云气象卫星系列介绍

风云气象卫星系列是中国于1977年开始研制的气象卫星系列&#xff0c;目前发射了风云一号、风云二号、风云三号、风云四号等卫星。 风云一号 FY-1卫星分为两个批次&#xff0c;各两颗星。01批的FY-1A星于1988年7月9日发射&#xff0c;FY-1B星于1990年9月3日发射。02批卫星在01批…

Word处理控件Aspose.Words功能演示:在 Java 中将 Word 文档转换为 EPUB

大多数智能设备&#xff0c;如智能手机、平板电脑、笔记本电脑等&#xff0c;都支持EPUB格式来查看或阅读文档。它是电子书或电子出版物的常用格式。另一方面&#xff0c;MS Word 格式&#xff0c;如DOCX、DOC等&#xff0c;是数字世界中广泛使用的文档格式之一。在本文中&…

Web3中文|NFT无法保障数字所有权?

来源 | nftnow 编译 | DaliiNFTnews.com 2021年&#xff0c;有这样一个头条新闻&#xff1a;一家投资公司以大约400万美元的价格在The Sandbox上买下了2000英亩的虚拟地产。 通过在以太坊区块链上购买792个NFT&#xff0c;该公司得到了元宇宙平台上的1200个城市街区。 但是…

家用宽带如何叠加多条宽带,提高局域网速度

前言 关于多条宽带如何合并&#xff0c;使局域网内带宽更快&#xff1f;通常我们在企业网络或实际项目中&#xff0c;随着用户的增加&#xff0c;一条或者几条带宽不能满足正常使用&#xff0c;便可以对带宽进行叠加&#xff0c;便于网络带度更快&#xff1b; 一、为什么要用…

web基础阶段的小兔鲜儿项目学习

小兔鲜儿1. 所用素材2. 项目文件介绍3. index页面的基本骨架4. 思路&#xff1a;先写外面大盒子和版心&#xff0c;由外往内写5. 源码&#xff1a;1. 所用素材 素材链接&#xff0c;点我跳转&#xff1a;https://download.csdn.net/download/angrynouse/87228151 2. 项目文件…

全国产!全志T3+Logos FPGA核心板(4核ARM Cortex-A7)规格书

核心板简介 创龙科技SOM-TLT3F是一款基于全志科技T3四核ARM Cortex-A7处理器 + 紫光同创Logos PGL25G/PGL50G FPGA设计的异构多核全国产工业核心板,ARM Cortex-A7处理单元主频高达1.2GHz。核心板CPU、FPGA、ROM、RAM、电源、晶振、连接器等所有器件均采用国产工业级方案,国产…

【HDU No. 4902】 数据结构难题 Nice boat

【HDU No. 4902】 数据结构难题 Nice boat 杭电OJ 题目地址 【题意】 有n 个数字a 1 , a 2 , …, an &#xff0c;每次都可以将[l , r ]区间的每个数字都更改为数字x &#xff08;类型1&#xff09;&#xff0c;或将[l ,r ]区间每个大于x 的ai 都更改为最大公约数gcd(ai , x …

云服务连续三年增长150%,网宿科技开拓新赛道

摘要&#xff1a;开拓云服务市场&#xff0c;网宿科技的打法。 提到网宿科技&#xff0c;很多人还停留在传统IT服务商的印象中。其实&#xff0c;网宿科技已经在一条新赛道加速前行&#xff0c;这就是云服务。 “借助亚马逊云科技的持续赋能&#xff0c;网宿科技积累了丰富的云…

swiper轮播图片+视频播放,预览及页面跳转功能

1.效果 2.上代码 <template> <swiper :circulartrue indicator-dots"true" change"changeSwiper" :autoplay"true" interval5000 classswiper-view><swiper-item class"swiper-img" v-for"(item,index) in swipe…

2022 CMU15-445 Project0 Trie

通过截图 在线测试 本地测试 总览 代码风格 我们的代码必须遵循 Google C Style Guide。在线检测网站使用 Clang 自动检查源代码的质量。如果我们的提交未通过任何这些检查&#xff0c;您的项目成绩将为零。 对于 Google C Style Guide &#xff0c;我们可以看这里 google-s…