数组--java--动态数组--有序数组--底层
创始人
2024-05-28 16:55:32
0

java数组

  • 基础--java中的数组
    • 创建数组
    • 空间占用
    • 初始化数组
    • 访问元素
    • 插入查找
    • 删除元素
  • 动态数组
    • 扩容
    • 插入和添加
    • 重写toString
    • 删除
  • 二维数组
    • 二维数组注意点
  • 有序数组
    • 实现
    • 测试


写在开头:


这篇文章包括数组的基础、一点底层的内容和一些稍微深入的东西。
作为第一个深入学习的数据结构,现在还不太知道怎么样了。有缺点请指出。
还有内容之后在补充。
本来是想和ArrayList源码一起来写进来的,但是发现实在不好插入进来了。还是到时候换一篇文章写了。

基础–java中的数组

数组是应用最广泛的数据存储结构。

因为里面元素是连续存储的,所以数组中的元素的地址可以用索引计算出来。
第iii个元素的地址:address=baseAddress(起始索引)+i∗sizeaddress = baseAddress(起始索引) + i*sizeaddress=baseAddress(起始索引)+i∗size
size是每一个元素所占的字节大小,如int占4,double占8

在许多语言中都把数组当作基本数据类型,但是在java中是把他们当作对象来对待的,所以在创建数组的时候使用new关键字。

创建数组

我们一般会把[]放在类型后面,清晰的代表着数据类型的一部分

int[] arr = new int[n];

像大部分的对象一样,arr只是作为存储这个对象的地址值。且大小固定,一旦创建就不可修改

空间占用

用int来介绍

  • 8字节的markword:记录对象的hash码等状态信息。这个具体会在java类介绍中。
  • 4字节的类指针:指定这个对象的类型,数据指向类的字节码文件。
  • 4字节的数组大小:所以最高2322^{32}232的容量
  • 数据元素+对其字节:内存对齐

初始化数组

创建数组后

  • 如果是基本数据类型会自动初始化数组

  • 如果是引用类型,则他们会是特殊的null对象

     如果尝试访问null的数据项,会出现Null Point Assignment(空指针赋值错误)
    

对于基本数据类型我们还可以通过{}来初始并创建数组

int[] arr= {1,2,3};

访问元素

第一个元素下标为0,所以容量为10的数组,下标为0-9.
越界访问会出现Array Index Out Of Bounds(数组越界错误)错误

插入查找

在n位置设置为num

arr[n]=num;

查询n位置的数

System.out.println(arr[n]);

删除元素

删除第n个元素
想要删除的话,将n后面的元素全部往前一个就可以了。

for(int i = n-1;iarr[i]=arr[i+1]
}
arr[arr.length-1]=0;

动态数组

因为普通数组,大小是写死的。很不方便,所以我们需要动态数组。
在java中有ArrayList类是已经实现了动态数组了。

这里介绍的是手写动态数组,但是不考虑泛型,只用整形数字

想要实现动态数组,那么我们需要一些属性来标记

  • 数组:我们需要一个基本数组来存储。
  • 大小:我们需要记录数组已经存储了的大小。
  • 容量:记录数组的大小,在不够用的时候进行扩容处理。
public class Array{private int size = 0;private int capacity = 8;private int[] array = new int[capacity];
}

添加
这个应该是用的最多的,所以我们先设计这个。
在不考虑扩容的情况下,在最后设置成element,大小加一就可以了。

public void add(int element){array[size] = element;size++;
}

插入
实现在index位置插入element:
我们需要将index之后的元素往后移动一位就可以实现了

public void insert(int index,int element){System.arraycopy(array,index,array,index+1,size-index);array[index]=element;
}	

我们需要对其进行容量判断,并实现扩容。

扩容

为了节省空间,在需要使用的时候在给数组空间。

private int[] array={};

对于扩容我们首先判断容量是否是0。

public void grow(){if(array.length > 0){capacity += capacity>>1;array = Arrays.copyOf(array,capacity);}else{capacity = 8;array = new int[capacity];}
}

插入和添加

然后我们可以改进我们的代码了。
是否满

private boolean isFull(){return size == capacity;
}

在index位置插入元素

public void insert(int index, int element){if (isFull()){//判断是否需要扩容grow();}if (index < 0 || index > size){//判断index是否合法throw new IndexOutOfBoundsException("Index: " + index + ", Size " + size);}System.arraycopy(array, index, array, index + 1, size - index);//将index后面的元素往后移动array[index] = element;size++;
}

在最后位置添加就可以复用代码了。

public void add(int element){insert(size,element);
}

测试:
测试代码中重写了toString方法,在下一节有。
在这里插入图片描述

重写toString

我们需要toString方法输出的只是我们的数组就可以了,所以这里需要重写toString方法。
这里建议使用append字符,而不是字符串,效率高。

@Override
public String toString() {StringBuilder sb = new StringBuilder();sb.append('[');for (int i = 0; i < size-1; i++) {sb.append(array[i]).append(',').append(' ');}sb.append(array[size-1]);sb.append(']');return sb.toString();
}

删除

将index索引位置元素删除:

  • 去除index索引元素
  • 后面元素前移
public int remove(int index){//判断index是否合法if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index: " + index + ", Size " + size);}int oldValue = array[index];//去除元素int numMoved = size - index - 1;//查看后面元素的数量if (numMoved > 0)System.arraycopy(array, index+1, array, index,numMoved);//将后面的元素往前移动array[--size] = 0; // clear to let GC do its workreturn oldValue;//返回删除的元素
}

二维数组

创建数组

int[][] array = new int[2][2];

初始化

int[][] arry = {{1,2,3},{2,3,4}
};

二位数组的实现:
起始就是一个数组存储着各种数组的地址值。
二维数组的实现

二维数组注意点

因为有缓存机制的影响,所以我们尽量在遍历的时候同一层的使用如:
int[x][y]

for(int i = 0;i

这样子速度会更快。

有序数组

在有序数组中,因为查询位置则会成为重点。所以我们会选择二分查询来加快速度。但不会书写二分查询的代码,而是直接调用API,不过需要学习的可以点击链接去看看。而动态数组中的内容也不在重复。
有序数组需要在动态数组的基础上实现。
很多也是复用了代码。
下面是不同点:

  • 对于给定位置插入和删除,我们不再对外公开所以权限给位private
  • 查询使用的Arrays的二分查询的api
  • 不用在判断位置是否合法了

实现

private int size = 0;
private int capacity = 0;
private int[] array = {};//扩容
public void grow() {if (array.length > 0) {capacity += capacity >> 1;array = Arrays.copyOf(array, capacity);} else {capacity = 8;array = new int[capacity];}
}//插入数据
private void insert(int index, int element) {if (isFull()) {//判断是否需要扩容grow();}if (index < 0 || index > size) {//判断index是否合法throw new IndexOutOfBoundsException("Index: " + index + ", Size " + size);}System.arraycopy(array, index, array, index + 1, size - index);//将index后面的元素往后移动array[index] = element;//插入元素size++;
}public void add(int element) {if (isFull()) {//判断是否需要扩容grow();}//二分查找元素应该插入的位置int i = Arrays.binarySearch(array, 0, size, element);if (i < 0) {i = -i - 1;}insert(i, element);
}private boolean isFull() {return size == capacity;
}public boolean delete(int index) {int i = Arrays.binarySearch(array, 0, size, index);if (i<0){return false;}remove(i);return true;
}
private void remove(int index) {int numMoved = size - index - 1;//查看后面元素的数量if (numMoved > 0)System.arraycopy(array, index + 1, array, index,numMoved);//将后面的元素往前移动array[--size] = 0; // clear to let GC do its work
}@Override
public String toString() {StringBuilder sb = new StringBuilder();sb.append('[');for (int i = 0; i < size - 1; i++) {sb.append(array[i]).append(',').append(' ');}sb.append(array[size - 1]);sb.append(']');return sb.toString();
}

测试

在这里插入图片描述

相关内容

热门资讯

花儿高中作文【最新6篇】 花儿高中作文 篇一:我的初恋初恋是每个人都会经历的一段特殊时光,而我的初恋也是我高中时期最美好的回忆...
完杀(优选3篇) 完杀 篇一近年来,电影市场上涌现出了一部部精彩的动作片,其中《完杀》无疑是备受瞩目的佳作。这部电影以...
以桥为题的高一作文【优选6篇... 以桥为题的高一作文 篇一桥,是连接两岸的纽带,是沟通交流的通道。它不仅仅是一座建筑物,更是一种象征,...
爱在平安夜的高二作文(优选6... 爱在平安夜的高二作文 篇一平安夜,这是一个充满温暖和祝福的夜晚。在这个特别的夜晚里,人们用不同的方式...
空手道馆游高一作文【通用3篇... 空手道馆游高一作文 篇一空手道馆是一个我一直向往前往的地方。终于,在高一的时候,我有机会参观了一家空...
我在等待的作文(优质3篇) 我在等待的作文 篇一等待,是一种不可避免的存在。无论是等待父母的归来,还是等待考试的成绩,亦或是等待...
缺陷美作文 缺陷美作文  在日常的学习、工作、生活中,大家或多或少都会接触过作文吧,作文是人们把记忆中所存储的有...
以英雄为题的高中作文(实用6... 以英雄为题的高中作文 篇一英雄的品质英雄是我们心中最崇高的存在,他们以无私的奉献和勇敢的行动,为社会...
温故与知新高一优秀作文800... 温故与知新高一优秀作文800字 篇一温故与知新温故而知新,可以为师矣。这句话出自《论语·为政》一章,...
互相尊重作文【优秀3篇】 互相尊重作文 篇一互相尊重是一种非常重要的品质,它可以帮助我们建立良好的人际关系,促进社会和谐的发展...
青春期(最新6篇) 青春期 篇一青春期是人生中一个重要的阶段,它标志着从儿童向成年的过渡。在这个时期,我们身心发生了许多...
高中优秀作文(优选6篇) 高中优秀作文 篇一:人生的选择与坚持人生就像一场马拉松比赛,我们每个人都在这条赛道上奋力前行。而在这...
高一作文开学第一课【通用6篇... 高一作文开学第一课 篇一开学第一课,让我明白了“自律”的重要性新学期开始了,我迫不及待地踏入高一的大...
细节决定成败的议论文【精选6... 细节决定成败的议论文 篇一细节决定成败,这是一个被广泛认同的观点。在人们追求成功的道路上,细节往往是...
竹君作文800字左右高二(精... 竹君作文800字左右高二 篇一:探索未知的世界在我们的生活中,有许多未知的领域等待我们去探索。这些未...
山东高考满分作文:丝瓜藤与肉... 山东高考满分作文:丝瓜藤与肉豆须 篇一丝瓜藤与肉豆须丝瓜藤和肉豆须都是我家院子里常见的植物。它们虽然...
冲刺高考的高三励志作文800... 篇一:冲刺高考的高三励志作文800字高三是每个学生都经历的一个重要阶段,也是冲刺高考的关键时期。在这...
上善若水高一作文【精选3篇】 上善若水高一作文 篇一标题:善良的力量善良是一种美德,它如同水一样,温润而宽容,给予人们希望和力量。...
志存高远方能远航高三作文(优... 志存高远方能远航高三作文 篇一在高三这个关键的学习阶段,我们作为学生要有志存高远的目标,才能在未来的...
高中英语作文|Healthy... 高中英语作文|Healthy Diet 健康饮食 篇一Title: The Importance o...