数组是一种连续内存空间的数据结构,利用java面向对象的优势,可以很好的实现数组
一.数组的定义
public class DynamicArray implements Iterable<Integer>{
//逻辑大小
private int size = 0;
//初始容量大小
private int capacity = 8;
// private int[] array = new int[capacity];
//将该数组初始化为一个空的
private int[] array ={};
}
属性有三个: 逻辑大小size, 数组容量capacity, 还有底层存储的实际数组array
这里可以直接定义好容量大小,也可以先暂时设置为空数组,后期在向数组添加元素的时候在进行设置容量
二.数组容量的检查和扩容
/**
* 检查并扩容
* 若size == capacity,则将容量扩大为原来数组的1.5倍
*
*/
public void checkAndExtend(){
//先检查size是否为0
if(size==0){
//给数组设置容量
array = new int[capacity];
//当size==capacity时就扩容
}else if (size == capacity){
capacity += capacity >>> 1;
int[] newArray = new int[capacity];
//将原来数组的内容复制到新数组中去
System.arraycopy(array,0,newArray,0,size);
//替换数组
array = newArray;
}
}
在检查的开始进行判断并设置容量即可
三.增加元素
/**
* 在数组末尾添加新元素
* @param element
*/
public void add(int element){
//在添加前进行检查容量
checkAndExtend();
array[size] = element;
size++;
}
该方法是在数组的末尾添加元素,
/**
* 按照指定位置添加元素
* @param index 位置索引
* @param element 元素
*/
public void addLast(int index,int element){
//在添加前进行检查容量
checkAndExtend();
if(index >= 0 && index<size){
System.arraycopy(array,0,array,index+1,size - index);
}
array[index] = element;
size++;
}
该方法是在指定的位置添加元素,这里有两个要点,
1.在所有的添加方法执行前先检查容量
2.利用System.arraycopy()方法,参数:1.要复制的数组 2.从该数组的哪个位置开始 3.要复制到的那个数组 4.从原数组的哪个位置开始 5.哪个位置结束
四.删除元素
/**
* 根据索引删除元素
* @param index 索引位置
* @return 该索引位置的值
* 流程:(1)从索引位置往后一位开始,将index+1到size-1的元素向前移动一位,
* (2)然后删除最后一个元素,
* (3)再把size减一
*/
public int remove(int index){
int removed = array[index];
if(index < size-1){
System.arraycopy(array,index+1,array,index,size-index-1);
}
size--;
return removed;
}
五.遍历数组
1.foreach循环遍历
public void foreach(){
for (int i = 0; i < size; i++) {
System.out.println(array[i]);
}
}
2.迭代器遍历(该方式必须实现Iterator接口)
/**
* 迭代器遍历
* @return Iterator对象
*/
@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循环,它的底层就是利用迭代器
//2.迭代器遍历数组
//增强for循环底层实现了迭代器
for (Integer item : dynamicArray) {
System.out.println(item);
}
3.函数式编程遍历
public void forEachFunction(Consumer<Integer> consumer){
for (int i = 0; i < size; i++) {
consumer.accept(array[i]);
}
}
该方法传参Consumer类,然后利用accept()方法,在这个方法里你可以执行自己编写的代码
dynamicArray.forEachFunction(System.out::println);
4.Stream流遍历
public IntStream stream(){
return IntStream.of(Arrays.copyOfRange(array,0,size));
}
利用XXXStream.of()方法,将数组转化为流,进行遍历
//3.stream流遍历 dynamicArray.stream().forEach(System.out::println);
六.插入删除性能
1.头部插入或删除,时间复杂度为O(n)
2.中间插入或删除,时间复杂度为O(n)
3.尾部插入或删除,时间复杂度为O(1)