数组的基本介绍:
空间占用:
JAVA中数组结构为:
8字节markword
4字节class指针(压缩class指针的情况)
4字节数组大小(决定了数组的大小为2的32次方
)
数组元素+对齐字节(JAVA中说有对象大小都是8字节的整数倍,不足的要用对齐字节对齐)
举个例子:比如 int[] a ={1,2,3,4,5}的大小为40个字节
组成如下
8+4+4+5*4+4=40
markword 8字节 4字节class指针 4字节数组大小 数组元素整型占4个字节 同上 同上 同上 同上 对齐字节和整型元素对齐占用4个字节
数组的添加:
数组尾部添加数据:
在JAVA 中数组的大小是固定的,我们首先定义一个有关数组的类,封装我们需要的属性和方法,和C语言的区别是JAVA用对象代替了指针(不知道我说的对不对,有懂的朋友欢迎指正)
我们定义一个整型的数组:
属性有:
int size;//数组中数据的长度
int capacity;数组的容量
int[] a =new int[capacity];//数组的总容量
private int size =0;
private int capacity =8;
private int[] array = new int[capacity];
在数组中按顺序插入元素:
public void addLast(int element){
add[size]=element;
size++;//数组元素增加之后,size就加一;
}
在数组内部键入数据:
public void add(int index, int element){
//首先判断要插入的位置是否合法
if(index>=0&&index<size){
//我们在插入数据的同时,为了保证数组的元素顺序不会发生变化,索引后的元素需要向后移动
//我们可以通过Java提供的Arraycopy函数来实现
System.Arraycopy(a,index,a,index+1,size-index);
a[index]=element;
size++;
}
}
数组的遍历:
因为数组的遍历方法很多,这里我就只说一种本人比较擅长的迭代器放法的遍历
首先定义的数组类需要实现Iterable这个接口
这个方法原本张这个样子,我们需要返回一个他的一个匿名内部类的对象方法
@Override
public Iterator<Integer> iterator() {
return null;
}
代码如下:
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int i = 0;
@Override
public boolean hasNext() {
return i < size;
}
@Override
public Integer next() {
return array[i++];
}
};
}
我们在主函数里面测试一下:
for (Integer integer : dy) {
System.out.println(integer);
}
}
直接调用增强for循环就可以实现,
全部代码如下图所示
package com.sjd.DynaArray;
public class TestDyA {
public static void main(String[] args) {
DynamicArray dy = new DynamicArray();
dy.addLast(1);
dy.addLast(2);
dy.addLast(3);
dy.foreach((element) ->{
System.out.println(element);
});
for (Integer integer : dy) {
System.out.println(integer);
}
}
}
package com.sjd.DynaArray;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;
public class DynamicArray implements Iterable<Integer>{
private int size =0;
private int capacity =8;
private int[] array = new int[capacity];
//在屁股后面插入元素
public void addLast(int element){
array[size] = element;
size++;
}
//在数组中间插入元素
public void add(int index,int element){
if (index>=0&&index<size) {
System.arraycopy(array,index,array,index+1,size-index);
array[index] = element;
size++;
}
}
//数组的遍历
public void foreach(Consumer<Integer> consumer){
for (int i=0;i<size;i++){
consumer.accept(array[i]);
}
}
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int i = 0;
@Override
public boolean hasNext() {
return i < size;
}
@Override
public Integer next() {
return array[i++];
}
};
}
}
数组的扩容:
首先我们先明确在什么情况下需要对数组进行扩容,那就是在添加数据时,我们要添加的数据个数超过了数组额定的长度,在这种情况下就需要我们进行对数组的扩容
具体逻辑是什么样的呢?
我们首先判断在添加数据的过程中,数组中是否有元素的存在,如果 数组中元素不存在的话,我们需要对数组的容量进行初始化
如果数组中的数据正好和数组初始化的容量相同的话我们就需要对数组进行进行扩容
我们在对数据进行添加操作的时候首先要判断数组是否需要初始化和扩容
public void extend(){
if (size == 0){
array = new int[capacity];
}else if (size == capacity){
//Java中扩容一般是按照原数组的1.5倍扩容
capacity +=capacity >>1;
int[] newarray = new int[capacity];
System.arraycopy(array,0,newarray,0,size);
array = newarray;
}