数组
概述:
定义:
数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识
因为数组内的元素是连续存储的,所以数组中元素的地址,可以通过其索引来计算。
int[] arr={1, 2, 3, 4, 5}
//索引 0 1 2 3 4
空间占用:
Java中数组结构为:
-
8字节的mark word(对象头,其中包含一些元信息,比如对象的哈希码,锁状态等)
-
4字节的类指针
-
4字节记录数组大小(决定数组最大容量为2^32)
-
数组元素
-
对齐字节(Java中所有对象大小都是8字节的整数倍,不足时要用对其字节补足)
例:
int[] arr={1, 2, 3, 4, 5};
的大小为40个字节(8 + 4 + 4 + 4 * 5 + 4)
动态数组:
与静态数组不同,可以实现增删改查;
自己实现:
1.一般实现
//DynamicsArray.java
package com.LL.test4;
public class DynamicsArray {
private int size = 0; //数组大小
private int capacity = 10; //数组容量
private int[] array = new int[capacity]; //创建数组(直接new出来一个)
public void addLast(int element) { //在数组末尾添加元素
array[size] = element;
size++;
}
public void add(int index, int element) {
//数组拷贝,把index索引位置空出来,然后给index索引位置赋值
System.arraycopy(array, index, array, index + 1, size - index);
array[index] = element;
}
public void printArray(){
for (int i = 0; i < size; i++) {
System.out.printf(array[i]+" ");
}
}
}
//ArrayTest.java
package com.LL.test4;
public class ArrayTest {
public static void main(String[] args) {
DynamicsArray arr = new DynamicsArray();
arr.addLast(1);
arr.addLast(2);
arr.addLast(3);
arr.addLast(4);
arr.add(2, 5);
arr.printArray();
}
}
上述代码可以改进:
public void addLast(int element) { //在数组末尾添加元素
add(size, element);
}
public void add(int index, int element) {
//数组拷贝,把index索引位置空出来,然后给index索引位置赋值
if (index >= 0 && index < size) {
System.arraycopy(array, index, array, index + 1, size - index);
}
//代码执行到这一步,说明index==size,可以代替方法addLast
array[index] = element;
size++;
}
完整代码:
package com.LL.test4;
import java.util.Iterator;
import java.util.function.Consumer;
public class DynamicsArray implements Iterable<Integer> {
private int size = 0; //数组大小
private int capacity = 10; //数组容量
private int[] array = new int[capacity]; //创建数组(直接new出来一个)
public void addLast(int element) { //在数组末尾添加元素
add(size, element);
}
public void add(int index, int element) {
//数组拷贝,把index索引位置空出来,然后给index索引位置赋值
if (index >= 0 && index < size) {
System.arraycopy(array, index, array, index + 1, size - index);
}
//代码执行到这一步,说明index==size,可以代替方法add
array[index] = element;
size++;
}
//遍历方式1
public void printArray() {
for (int i = 0; i < size; i++) {
System.out.printf(array[i] + " ");
}
}
//遍历方式2
public void printArray1(Consumer<Integer> consumer) {
//printArray为函数式接口提供array[i],函数式接口为方法返回void,可以考虑Consumer函数式接口
//Consumer底层方法: void accept(T t);
for (int i = 0; i < size; i++) {
consumer.accept(array[i]);
}
}
//遍历方式3
//思路:让DynamicsArray实现Iterable接口,再重写接口中的抽象方法
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
//匿名内部类,由于Iterator<Integer>是一个接口,先写一个接口的实现类,再new创建一个实现类的对象
int i = 0;
@Override
public boolean hasNext() { //判断是否有元素
return i < size;
}
@Override
public Integer next() { //获取元素,移动指针
return array[i++];
}
};
}
}
//ArrayTest.java
package com.LL.test4;
public class ArrayTest {
public static void main(String[] args) {
DynamicsArray arr = new DynamicsArray();
arr.addLast(1);
arr.addLast(2);
arr.addLast(3);
arr.addLast(4);
arr.add(2, 5);
//遍历方式1
arr.printArray();
//遍历方式2
arr.printArray1(new Consumer<Integer>() { // 左边代码也可以使用Lambda表达式简化:
@Override // arr.printArray1(element -> {
public void accept(Integer integer) { // System.out.printf(element + " ");
System.out.printf(integer + " "); // });
}
});
//遍历方式3
for (Integer i : arr) { //增强for遍历
System.out.printf(i + " "); //格式: for(元素的数据类型 变量名: 数组/集合){
} // }
}
}