数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

时间:2021-07-10 00:19:53

数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接如下,可点击跳转:

链接:https://blog.csdn.net/pjh88/article/details/107166950

什么是数组与动态数组?

数组

数组是相同数据类型的元素按照一定的顺序排列的集合,若将有限个类型相同的变量的集合命名,那么这个名称称为数组名,组成数组的各个变量称为数组的分量,也称为数组的元素,有时爷称为下标变量,用于区分数组的各个元素的数组编号称为下标。数是程序设计中,为了处理方便把具有相同类型的若干变量按有序的形式组织起来的一种形式,这些按序排序的同类元素的集合称为数组

动态数组

顾名思义,动态数组即可以动态扩容的数组,一般的数组是不能扩容的,及在创建数组对象的时候就规定了数组的大小,规定数组是多大就是多大,后期不可以存储多余的元素

动态数组的好处也显而易见:

1.动态的增加和减少元素

2.实现collection和list接口

3.灵活设置数组的大小

java中已经给我们封装好了一个动态数组Arraylist的类,我们可以直接使用,其内部有许多方法,我们先来看看有什么方法,下面仅仅讲我们经常使用到的方法那些不怎么使用的我们在这就不讲了:

int size();元素的数量
boolean isEmpty();是否为空
boolean contains(E element); 判断是否包含某个元素
void add(E element) ;添加元素到最后
E get(int index);返回index对应位置的元素
E set(int index,E element);往index位置添加元素
void add(int index,E element);往index位置添加元素
E remove(int index); 删除index位置对应的元素
int indexOf(E element); 查看元素的位置
void clear();清除所有元素

接下来我们逐一讲解这些方法

定义的变量

    //元素的数量
private int size;
//存储元素
private E[] elements;
//初始化大小
private static final int DEFAULT_CAPACITY=16;
//元素没有找到时的放回值
private static final int ELEMENT_NOT_FOUND=-1;

构造方法

 //自定义大小
public ArrayList(int capacity){
//如果传入的大小小于默认数组的大小,则使用默认的大下
capacity= (capacity<DEFAULT_CAPACITY)?DEFAULT_CAPACITY:capacity;
elements=(E[])new Object[capacity];
} //默认大小的构造方法
public ArrayList(){
this(DEFAULT_CAPACITY);
}

判断index的范围有没有越界

public void rangeCheak(int index){
if (index<0||index>size){
outofBounds(index);
}
}

获取指定位置的元素

public E get(int index){
rangeCheak(index);
return elements[index];
}

重新设定指定位置的元素

 public E set(int index,E element){
//检查插入位置是否合法
rangeCheak(index);
//返回原来的元素
E oldelement1 = elements[index];
//插入新的元素
elements[index]=element;
return oldelement1;
}

判断是否为空

 public boolean isEmpty(){
return size==0;
}

返回元素的数量

 public int size(){
return size;
}

判断是否包含某个指定元素

public boolean contains(E element){
return indexOf(element)!=ELEMENT_NOT_FOUND;
}

返回指定元素的位置

public int indexOf(E element){
if (element==null){
for (int i = 0; i < size; i++) {
if (elements[i]==null){
return i;
}
}
}else{
for (int i = 0; i < size; i++) {
if (element.equals(elements[i])){
return i;
}
}
}
return ELEMENT_NOT_FOUND;
}

在末尾插入元素

public void add(E element){
add(size,element);}

在指定位置插入元素

public void   add(int index,E element){
//检查范围
rangeCheakForadd(index);
//判断容量是否足够
ensureCapacity(size+1);
for (int i = size; i > index; i--) {
elements[i]=elements[i-1];
}
elements[index]=element;
size++;
}

检查插入范围

public void rangeCheakForadd(int index){
if (index<0||index>size){
outofBounds(index);
}
}

移除指定位置的元素

 public  E remove(int index){
//检查范围
rangeCheak(index);
E removeElement = elements[index];
for (int i=index+1;i<size;i++) {
elements[i-1]=elements[i];
}
elements[--size]=null;
return removeElement;
}

清除所有元素

public void clear(){

for (int i = 0; i < size; i++) {

elements[i]=null;

}

}

数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

其实动态数组最重要的一个方法就是扩容,下面来重点讲解

public void ensureCapacity(int capacity){
int oldcapacity = elements.length;
//如果比原来小则不做改变
if (oldcapacity>= capacity){
return;
}
//使用位运算,速度更快
//我这里用的是二倍扩容,这里的扩容大小可以自己来设置,以达到最高的使用率
int newCapacity=oldcapacity+(oldcapacity>>1);
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i]=elements[i];
}
//将elements的地址赋值新的地址
elements=newElements;
System.out.println(oldcapacity+"扩容为:"+newCapacity);
}

复写toString()方法

@Override
public String toString(){
//使用StringBuilder
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('[');
for (int i = 0; i < size; i++) {
if (i!=0){
stringBuilder.append(",");
}
stringBuilder.append(elements[i]);
}
stringBuilder.append(']');
return stringBuilder.toString();
}

以上就是对java动态数组源码的解析,后面我会继续更新其他知识,写作不易,请各位老铁点个赞支持一下,觉得有帮助的也可以收藏呀,我会经常更新文章,也可以关注我呀

数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解的更多相关文章

  1. 数据结构与算法系列2 线性表 链表的分类&plus;使用java实现链表&plus;链表源码详解

    数据结构与算法系列2.2 线性表 什么是链表? 链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个 ...

  2. javascript实现数据结构与算法系列:线性表的静态单链表存储结构

    有时可借用一维数组来描述线性链表,这就是线性表的静态单链表存储结构. 在静态链表中,数组的一个分量表示一个结点,同时用游标(cur)代替指针指示结点在数组中的相对位置.数组的第0分量可看成头结点,其指 ...

  3. Mybatis源码详解系列&lpar;四&rpar;--你不知道的Mybatis用法和细节

    简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...

  4. Java源码详解系列&lpar;十&rpar;--全面分析mybatis的使用、源码和代码生成器&lpar;总计5篇博客&rpar;

    简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository ...

  5. JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)

    前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...

  6. 源码详解系列&lpar;六&rpar; ------ 全面讲解druid的使用和源码

    简介 druid是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,druid还扩展 ...

  7. 源码详解系列&lpar;七&rpar; ------ 全面讲解logback的使用和源码

    什么是logback logback 用于日志记录,可以将日志输出到控制台.文件.数据库和邮件等,相比其它所有的日志系统,logback 更快并且更小,包含了许多独特并且有用的特性. logback ...

  8. 源码详解系列&lpar;八&rpar; ------ 全面讲解HikariCP的使用和源码

    简介 HikariCP 是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,和 dr ...

  9. 套用GGTalk做项目的经验总结——GGTalk源码详解系列(一)

    坦白讲,我们公司其实没啥技术实力,之所以还能不断接到各种项目,全凭我们老板神通广大!要知道他每次的饭局上可都是些什么人物! 但是项目接下一大把,就凭咱哥儿几个的水平,想要独立自主.保质保量保期地一个个 ...

随机推荐

  1. BZOJ2510&colon; 弱题

    求k时刻一个标号转移到各位置的概率,最后枚举每个标号加权求期望.可以发现转移矩阵是循环矩阵,因此乘法是n^2的.另外这个乘法是圆周卷积的形式,然后就作死写了发fft,发现精度升天了= = #inclu ...

  2. Python爬虫Scrapy框架入门(1)

    也许是很少接触python的原因,我觉得是Scrapy框架和以往Java框架很不一样:它真的是个框架. 从表层来看,与Java框架引入jar包.配置xml或.property文件不同,Scrapy的模 ...

  3. three&period;js 源码注释(四十四)Light&sol;DirectionalLight&period;js

    /** * * DirectionalLight方法 根据设置灯光的颜属性color, 强度属性intensity创建平行光光源. * DirectionalLight 对象的功能函数采用定义构造的函 ...

  4. js实现瀑布流的一种简单方法实例分享

    现在说瀑布流式布局似乎有点晚了,但是每一项技术都是向着“精”和“简”的方向在不断发展,在发展到极致之前,需要一个相当漫长的过程,因此,从这个角度来说,当瀑布流被应用得越来越多的时候,反而更应该讨论它, ...

  5. 添加Pods后,import无提示的解决办法

    选择工程的 Target -> Build Settings 菜单,找到\”User Header Search Paths\”设置项 新增一个值"$(PODS_ROOT)" ...

  6. xml bug

    在Eclipse 创建动态WEB 工程,在src 下 创建 config.xml: 1 <?xml version="1.0" encoding="UTF-8&qu ...

  7. Android 桌面不显示应用图标

    忽然有一天,运行自己的程序,发现桌面没有应用图标了. google了半天,也没什么发现. 最后发现是主Activity中: <action android:name="android. ...

  8. 动态代理处理service

    /* 动态代理处理service * 1.动态代理的核心是切面编程,去除重复代码: * 2.通过反射+注解可以灵活的获取传入对象内容: * 3.通过try+catch将多个操作包裹,实现事物的原子性: ...

  9. 2018-2019-2 20175205实验一《Java开发环境的熟悉》实验报告

    2018-2019-20175205实验一<Java开发环境的熟悉>实验报告 实验步骤 (一)命令行下Java程序开发 在Linux下运行结果: 在IDEA中运行结果: (二)IDEA下J ...

  10. iOS逆向开发(2):获取APP的类声明 &vert; class-dump &vert; dumpdecrypted

    之前介绍了怎么操作越狱的iOS设备(以下简称为手机),但简单操作手机并不是目标,小程的目标是手机上特定的APP,比如微信.淘宝.QQ音乐等等,因为小程可以从这些APP上拿到一些有用的信息或资源--比如 ...