实现动态数组的增删改查并测试
List 接口
既然线性结构可以由顺序存储结构和链式存储结构实现
那么将两者对线性结构共同的操作进行抽取,定义出线性结构的接口
import java.util.Comparator;
public interface List<E> extends Iterable<E> {
//默认在表尾添加一个元素
public void add(E element);
//在指定角标处添加元素
public void add(int index, E element);
//删除指定元素
public void remove(E element);
//删除指定角标的元素,并返回原线值
public E remove(int index);
//获取指定角标处的元素
public E get(int index);
//修改指定角标index处的值为element 并返回原先值
public E set(int index, E element);
//获取线性表中元素个数
public int size();
//查看元素第一次出现的角标位置(从左到右)
public int indexOf(E element);
//判断是否包含元素
public boolean contains(E element);
//判断线性表是否为空1
public boolean isEmpty();
//清空线性表
public void clear();
//按照比较器的内容进行排序
public void sort(Comparator<E> c);
//获取子线性表 原线性表中[fromIndex, toIndex]这个部分
public List<E> subList(int fromIndex, int toIndex);
}
创建ArrayList类实现List接口
既定义相关成员属性和构造函数
并有系列增删改查等操作修改为本身需要的
import p1.接口.List;
import java.util.Comparator;
import java.util.Iterator;
//自定义线性表的顺序储存方式
public class ArrayList<E> implements List<E> {
//定义数组容器 data.length指的是当前数组容量
private E[] data;
//元素个数size == 0 线性表为空 size == data.length满了
private int size;
//默认容量 全局变量
private static int DEFAULT_CAPACITY = 10;
//默认构造函数:创建一个默认容量为10的线性表
public ArrayList(){
data = (E[]) new Object[DEFAULT_CAPACITY];
size = 0;
}
//指定默认容量的构造函数 线性表
public ArrayList(int capacity){
if(capacity <= 0 ){
throw new IllegalArgumentException("capacity must > 0");
}
DEFAULT_CAPACITY = capacity;
data = (E[]) new Object[DEFAULT_CAPACITY];
size = 0;
}
//指定数组的构造函数:传入一个,将他封装成为一个线性表
//[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
public ArrayList(E[] arr) {
if(arr == null || arr.length == 0){
throw new IllegalArgumentException("arr can not be null");
}
data = (E[]) new Object[DEFAULT_CAPACITY];
for(int i = 0; i < arr.length; i++){
add(arr[i]);
}
}
@Override
public void add(E element) {
add(size, element);
}
@Override
public void add(int index, E element) {
if(index < 0 || index > size){
throw new IllegalArgumentException("add index out of range");
}
//判断线性表是否满状态
if (size == data.length){
resize(2 * data.length);
}
//向后移动元素
for (int i = size - 1; i >= index ; i--) {
data[i + 1] = data[i];
}
//将新元素插入到指定位置
data[index] = element;
size++;
}
//扩容/缩容操作 不应该向外界提供
private void resize(int newLen) {
E[] newData = (E[])new Object[newLen];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData;
}
@Override
public void remove(E element) {
//删除指定元素 只删除一次 && 删除所有指定元素
int index = indexOf(element);
if(index != 1){
remove(index);
}
}
@Override
public E remove(int index) {
if (index < 0 || index >= size){
throw new IllegalArgumentException("remove index out of range");
}
//先保存要删除的值
E ret = data[index];
//移动元素
for (int i = index + 1 ; i < size; i++) {
data[i - 1] = data[i];
}
//将新元素添加到指定位置
size--;
//什么时候缩容
//1.有效元素是容量的四分之一
//2.当前容量不得小于等于默认容量
if(size == data.length / 4 && data.length > DEFAULT_CAPACITY){
resize(data.length / 2);
}
return ret;
}
@Override
public E get(int index) {
if(index < 0 || index >= size ){
throw new IllegalArgumentException("get index out of range ");
}
return data[index];
}
@Override
public E set(int index, E element) {
if(index < 0 || index >= size ){
throw new IllegalArgumentException("set index out of range ");
}
E ret = data[index];
data[index] = element;
return ret;
}
@Override
public int size() {
return size;
}
//额外添加一个函数 获取线性表中那个数组的容量
private int getCapacity(){
return data.length;
}
@Override
public int indexOf(E element) {
for (int i = 0; i < size; i++) {
if (data[i] == element) {
return i;
}
}
return -1;
}
@Override
public boolean contains(E element) {
return indexOf(element) != -1;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void clear() {
data = (E[])new Object[DEFAULT_CAPACITY];
size = 0;
}
@Override
public void sort(Comparator<E> c) {
if(c == null){
throw new IllegalArgumentException("comparator can not be null");
}
for (int i = 1; i < size; i++) {
E e = data[i];
int j = 0 ;
for (j = 1; j > 0 && c.compare(data[j - 1], e ) > 0; j--) {
data[j] = data[j - 1];
}
data[j] = e ;
}
}
@Override
public List<E> subList(int fromIndex, int toIndex) {
if(fromIndex < 0 || toIndex >= size || fromIndex > toIndex){
throw new IllegalArgumentException("must 0 <= fromIndex <= toIndex <= size - 1");
}
ArrayList<E> List = new ArrayList<>();
for(int i = fromIndex; i <= toIndex; i++){
List.add(data[i]);
}
return List;
}
@Override
public boolean equals(Object o) {
//1.判空
if(o == null){
return false;
}
//2.判自己
if (this == o) {
return true;
}
//3.判类型
if(o instanceof ArrayList){
//4.比较
ArrayList<E> other = (ArrayList<E>) o;
//5.先比个数
if (size != other.size){
return false;
}
//6.有效元素个数相等的情况下,逐个比较元素
for (int i = 0; i < size; i++) {
if (!data[i].equals(other.data[i])){
return false;
}
}
return true;
}
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
if(isEmpty()){
sb.append(']');
}else{
for (int i = 0; i < size; i++) {
sb.append(data[i]);
if (i == size - 1){
sb.append(']');
}else{
sb.append(',');
sb.append(' ');
}
}
}
return sb.toString();
}
//获取当前容器的迭代器
//通过迭代器对象更方便挨个取出每一个元素
//同时 实现了Iterable 可以让当前的数据结构/容器 被foreach循环遍历
@Override
public Iterator<E> iterator() {
return new ArrayListIterator();
}
//创建一个属于ArrayList的迭代器
class ArrayListIterator implements Iterator<E>{
private int cur = 0;
@Override
public boolean hasNext() {//判断是否有下一个元素
return cur < size;
}
@Override
public E next() {//如果有下一个,则把当前元素返回,并跳到下一个
return data[cur++];
}
}
}
三、测试
用于测试所做的动态数组crud操作是否能正常运行
import java.util.Comparator;
import java.util.Iterator;
import java.util.Random;
public class TestArrayList02 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
System.out.println(list);
Random random = new Random();
for (int i = 0; i < 10; i++) {
list.add(random.nextInt(100));
}
System.out.println(list);
for (int i = 0; i < 10; i++) {
list.add(0, i);
}
System.out.println(list);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(list);
for (Integer num : list) {
System.out.println(num);
}
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
}
结果如下
[]
[11, 88, 34, 32, 67, 9, 1, 54, 91, 21]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 11, 88, 34, 32, 67, 9, 1, 54, 91, 21]
[91, 21, 7, 6, 5, 4, 3, 2, 1, 0, 11, 88, 34, 32, 67, 9, 1, 54, 91, 21]
91
21
7
6
5
4
3
2
1
0
11
88
34
32
67
9
1
54
91
21
91 21 7 6 5 4 3 2 1 0 11 88 34 32 67 9 1 54 91 21