动态数组
添加新元素时,实现自动扩容功能。参考ArrayList实现。
实现功能
- 添加功能
- 末尾添加
- 头添加
- 任意位置添加
- 删除功能
- 根据下标删除元素
- 根据值删除元素(删除第一次出现的值)
具体实现
DynamicArray 结构
public class DynamicArray implements Iterable<Integer>{
private int size = 0; // 逻辑大小
private int capacity = 8; // 容量
private int[] array = {};
}
扩容方法
private void checkCapacity() {
if (size==0){
array = new int[capacity];
}else if (size==capacity){
// 1.5倍扩容
capacity += capacity>>1;
// 第一种 可以使用这个api直接返回一个有新容量的array;
// array = Arrays.copyOf(array, capacity);
// 第二种,System.arraycopy() Arrays.copyOf封装了该函数
int[] copy = new int[capacity];
System.arraycopy(array,0,copy,0,capacity);
array = copy;
}
}
添加功能
添加时需要注意元素整体移动。具体方法实现底层都是add()方法。
/**
* 末尾添加元素
* * @param target
*/
public void addLast(int target){
this.add(size,target);
}
/**
* 添加元素
* @param index 插入的位置
* @param target 待插入的值
*/
private void add(int index, int target) {
checkCapacity();
if (index>=0&&index<=size){
// 复制 插入位置的数据向后移一位 eg:[2,3,?(index),5,6]
System.arraycopy(array,index,array,index+1,size-index);
array[index] = target;
size++;
}else {
// index输入问题。抛出异常或者打印错误信息
System.out.println("index输入异常");
}
}
/**
* 在头部添加
* @param target
*/
public void addFirst(int target){
this.add(0,target);
}
/**
* 任意位置添加
* @param index 下标
* @param target 目标值
*/
public void addIndex(int index,int target){
this.add(index,target);
}
删除功能
/**
* 根据下标删除
* @param index
* @return
*/
public int removeOfIndex(int index){
if (index<0||index>=size){
//保证数据,可以抛出异常等操作
System.out.println("错误!");
throw new RuntimeException("index不存在");
}
return this.delete(index);
}
/**
* 根据值删除
* @param target 目标值
* @return -1删除错误, 目标值
*/
public int removeOfValue(int target){
for (int i = 0; i < size; i++) {
if (target==array[i]){
return this.delete(i);
}
}
return -1;
}
/**
* 在[0,Size)之间 删除元素
* @param index 下标位置
*/
private int delete(int index){
//直接覆盖即可
int temp = array[index];
System.arraycopy(array,index+1,array,index,array.length-index-1);
size--;
return temp;
}
遍历方法
实现Iterable接口,并实现iterator(),动态数组就可以使用增强for循环
for (Integer integer : array) {
System.out.println(integer);
}
具体实现
- 重写iterator(),返回一个Iterator对象
- 主要方法:hasNext,next两个方法
- haseNext->判断下一个元素是否存在
- next返回迭代元素,并更新下一个元素。
@Override
public Iterator<Integer> iterator() {
// 返回一个可迭代对象。
return new Iterator<Integer>() {
// 开始遍历的起始下标
int i = 0;
@Override
public boolean hasNext() {
// 判断下标是否越界
// true->存在,反之则
return i < size;
}
@Override
public Integer next() {
// 返回迭代元素,更新i
return array[i++];
}
};
}
完整实现
package array;
import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;
/**
* @author hly
* @version 1.0
*/
public class DynamicArray implements Iterable<Integer>{
private int size = 0; // 逻辑大小
private int capacity = 8; // 容量
private int[] array = {};
/**
* 末尾添加元素
* * @param target
*/
public void addLast(int target){
this.add(size,target);
}
/**
* 添加元素
* @param index 插入的位置
* @param target 待插入的值
*/
private void add(int index, int target) {
checkCapacity();
if (index>=0&&index<=size){
// 复制 插入位置的数据向后移一位 eg:[2,3,?(index),5,6]
System.arraycopy(array,index,array,index+1,size-index);
array[index] = target;
size++;
}else {
// index输入问题。抛出异常或者打印错误信息
System.out.println("index输入异常");
}
}
/**
* 在头部添加
* @param target
*/
public void addFirst(int target){
this.add(0,target);
}
/**
* 任意位置添加
* @param index 下标
* @param target 目标值
*/
public void addIndex(int index,int target){
this.add(index,target);
}
/**
* 根据下标删除
* @param index
* @return
*/
public int removeOfIndex(int index){
if (index<0||index>=size){
//保证数据,可以抛出异常等操作
System.out.println("错误!");
throw new RuntimeException("index不存在");
}
return this.delete(index);
}
/**
* 根据值删除
* @param target 目标值
* @return -1删除错误, 目标值
*/
public int removeOfValue(int target){
for (int i = 0; i < size; i++) {
if (target==array[i]){
return this.delete(i);
}
}
return -1;
}
/**
* 在[0,Size)之间 删除元素
* @param index 下标位置
*/
private int delete(int index){
//直接覆盖即可
int temp = array[index];
System.arraycopy(array,index+1,array,index,array.length-index-1);
size--;
return temp;
}
/**
* 遍历方法3 - stream 遍历
*
* @return stream 流
*/
public IntStream stream() {
return IntStream.of(Arrays.copyOfRange(array, 0, size));
}
/**
* 检查容量
*/
private void checkCapacity() {
if (size==0){
array = new int[capacity];
}else if (size==capacity){
// 1.5倍扩容
capacity += capacity>>1;
// 第一种 可以使用这个api直接返回一个有新容量的array;
// array = Arrays.copyOf(array, capacity);
// 第二种,System.arraycopy() Arrays.copyOf封装了该函数
int[] copy = new int[capacity];
System.arraycopy(array,0,copy,0,capacity);
array = copy;
}
}
public int getValue(int index){
return array[index];
}
@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 foreach(Consumer<Integer> consumer) {
for (int i = 0; i < size; i++) {
// 提供 array[i]
// 返回 void
consumer.accept(array[i]);
}
}
}
main方法调用
public static void main(String[] args) {
DynamicArray array = new DynamicArray();
array.addLast(1);
array.addLast(2);
array.addFirst(3);
array.addIndex(2,5);
array.stream().forEach((item)-> System.out.printf("%d ",item));
System.out.println();
int delete = array.removeOfIndex(0);
System.out.println("删除的数据:"+delete);
int i = array.removeOfValue(2);
System.out.println("删除的数据:"+i);
array.stream().forEach((item)-> System.out.printf("%d ",item));
array.foreach(System.out::println);
Iterator<Integer> iterator = array.iterator();
// 迭代
System.out.println("iterator迭代方法");
while (iterator.hasNext()){
System.out.println(iterator.next());
}
for (Integer integer : array) {
System.out.println(integer);
}
}