热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JAVA用数组实现动态数组——顺序表

JAVA用数组实现动态数组——顺序表,Go语言社区,Golang程序员人脉社

数组是我们在编程的过程中最常用到的数据结构。一般我们用的都是定长数组,动态数组用的会比较少。但是有时,或者说有很多时候,定长数组并不能很好地满足我们的要求,于是我们只能用动态数组。在JAVA中,有一个封装好的API——ArrayList,就是一个动态数组,在C++中有一个vector也是动态数组。我们可以直接拿过来使用。但是有时我们可能需要自己定制一个动态数组,以便更好地解决我们的问题。今天,我们就来用JAVA实现一个动态数组。实现动态数组的方法有两种,一种是用定长数组实现(顺序表),另一种是用引用(链表)实现。今天我们讲的是定长数组实现的方法。

一、基本概念

1、数组是一个容器,可以存储同一类型的N个数据。数组是一种数据结构,直接通过下标进行定位,是数据结构中访问速度最快的一种。它属于引用数据类型(数组名中存储的是内存首地址)。
数组本身只有length属性(length获取数组中能存储的数据个数),但是有从Object父类继承的属性和方法。
2、数组在内存中的存储:
        数组在内存中是一个连续的存储空间。
        一维数组、二维数组、......

以二维数组为例,它的空间结构如下:

二、实现的基本思路(定长数组实现动态数组的):

1、实现过程:首先先申请一个定长的数组空间Original,定义一个int型的数据len,记录当前已使用的空间大小,也就是动态数组的长度。然后在每次涉及到增加元素的操作中对当前动态数组的长度和已开辟的空间大小进行比较。如果len>=length,那么我们就新开辟一个大小为Original.length()*2的新定长数组,先把原来数组的信息赋值到这个新的数组中,再增加新的数据。如果len

定长数组长度不足时

定长数组长度足够时

2、细节:

A、将待存储的数据定义为Object,因为Object是所有类的父类,因此我们就可以往这个数组中加入任何类型的数据。
B、有时我们要求数组中只能存储某一种数据类型,不能掺杂其他数据;有时我们又希望要求数组中可以存储任何数据类型。要满足这两个看似有些矛盾的要求就只能使用Java的泛型。泛型不是引用类型也不是基本数据类型;泛型是一种特殊的符号,它泛指Java中任何一种引用类型。泛型起到一个占位符的作用,之后在使用的过程中可以根据项目的具体需求来指定占位符的数据类型。

二、动态数组需要实现哪些功能

1.动态添加add方法;

2.获取任意位置的数据get方法;

3.返回当前动态数组的长度;

4.在任意位置插入数据的insert方法;

5.删除任意位置数据的delete方法;

6.合并其他数组的unite方法;

这里的话,前三个方法是必须要有的,后三个可有可无,根据具体的题目来决定。如果还需要其他方法可以自行增加。

三、具体代码和解析

//实现一个动态数组
public class DynamicArray {
	//申请一个数组,初始定长是100
	Object[] Original;
	private int startLength=100;
	int len=0;//当前长度
	
	//不给数组的初始长度,使用默认的初始长度
	public DynamicArray(){
		Original=new Object[startLength];
	}
	
	//给定初始数组长度
	public DynamicArray(int startLength){
		this.startLength=startLength;
	}
	
	//添加数据的方法
	public void add(E o) {
		//当前所用长度和数组可用长度相等
		if(len==Original.length) {
			//将数组的长度扩展一倍
			Object[] newArray= new Object[Original.length*2];
			//保存原来的值
			for(int i=0;iOriginal.length) {
			Object[] newArray= new Object[(dArray.size()+len)*2];
			for(int i=0;i
//定义一个测试类
public class Test {
	
		public int data;
		
		public Test(int data) {
			this.data=data;
		}
	
	public static void main(String[] args) {
		Test t1=new Test(1);
		Test t2=new Test(2);
		Test t3=new Test(3);
		
		DynamicArray dynamicArray=new DynamicArray();
		dynamicArray.add(t1);
		dynamicArray.add(t2);
		dynamicArray.add(3);
		dynamicArray.insert(t3, 1);
		dynamicArray.delete(0);
		
		DynamicArraydynamicArray2=new DynamicArray();
		dynamicArray2.add(t1);
		//dynamicArray2.add(3);//这个方法会报错,因为指定了泛型的具体数据类型
		
		dynamicArray.unite(dynamicArray2);
		
		int len=dynamicArray.size();
		System.out.println("length="+len);
		for(int i=0;i

四、反思总结

1.如果开辟了新数组,一定要把原来的Original指向新的数组,否则数组不会更新。因为函数中的数组属于局部变量,一旦这个被调用方法返回之后这个数组空间就会被释放了。

Original=newArray;

2.这里我们选择的是双倍扩展数组空间,目的是为了降低算法的空间复杂度。如果采用每增加一个元素增加一个数组空间的话,每次添加函数都要进行一次赋值操作,该操作的时间复杂度是n,一旦n值较大,就会大大降低算法的运算效率

3.Object类是所有类的父类,因此我们这里在实现动态数组的时候参数类型设置为Object后就可以适用于任意类的对象。不过在获取这个动态数组的对象时,记得把得到的Object类强制转化为具体的类

			//这里需要强制转型
			Object x=dynamicArray.get(i);
			Test changex=(Test)x;

推荐阅读
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 集合的遍历方式及其局限性
    本文介绍了Java中集合的遍历方式,重点介绍了for-each语句的用法和优势。同时指出了for-each语句无法引用数组或集合的索引的局限性。通过示例代码展示了for-each语句的使用方法,并提供了改写为for语句版本的方法。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
author-avatar
天狼飞虎神印
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有