package test; /*
-
总结:这个没啥特别难的跟坑点,我当时刚学也没花啥时间就写完了。
-
主要就只有一个扩容问题,难点应该就是用的System.arrayCopy的4个参数的理解。
-
我当时基本就纯靠猜的参数,然后画图就搞定扩容的问题了。
-
心得就是学会画图去具象化问题。 */ public class MyArrayTest {
public static void main(String[] args) { MyArrayList mal = new MyArrayList(); mal.add(1); mal.add(2); mal.insert(0, 11); mal.insert(0, 12); mal.insert(0, 13); mal.insert(0, 14); mal.insert(0, 15); mal.insert(0, 16); mal.insert(0, 17); mal.insert(0, 18); mal.insert(0, 4); mal.insert(0, 5); mal.insert(0, 0); mal.insert(0, 7); mal.insert(0, 0); mal.insert(0, 5); mal.insert(0, 6); mal.insert(0, 2); mal.insert(0, 0); mal.remove(0); for(int i=0; i<mal.objs.length;i++) { System.out.println(mal.objs[i]); }
System.out.println(mal.index); System.out.println(mal.objs.length);} }
class MyArrayList{ //底层是数组。所以有序可以重复。 Object[] objs; //用来定位目标元素以及判断数组列表是否为空的。 int index = -1; public MyArrayList() { //初始化容量为16 this(new Object[16]); }
public MyArrayList(Object[] objs) {
//有参构造强制数组长度为2的幂。并重新封装防止外部直接修改。外部数组元素内部有null会有bug懒得改了。
if(objs == null) {
this.objs = new Object[16];
return;
}
int capacity = Math.max(16, objs.length);
this.objs = new Object[capacity];
System.arraycopy(objs, 0, this.objs, 0, objs.length);
this.index = objs.length - 1;
}
public void display() {
if(this.index == -1) return;
for(int i=0;i<objs.length;i++) {
System.out.println(objs[i]);
}
}
public boolean contains(Object obj) {
return (this.get(obj) >= 0) ? true : false;
}
private void capacity() {
//数组扩容为原数组长度的2倍
Object[] newArrayList = new Object[objs.length*2];
System.arraycopy(objs, 0, newArrayList, 0, objs.length);
this.objs = newArrayList;
}
public boolean add(Object obj) {
if(obj == null) return false;
//超出数组长度时触发扩容
if(index == objs.length) {
this.capacity();
}
//只对空元素进行赋值。刚开始学写考虑不周到。懒得改了。
for(int i=0;i<objs.length;i++) {
if(objs[i] == null) {
objs[i] = obj;
break;
}
}
index++;
return true;
}
public boolean insert(int index,Object obj) {
if(obj == null) return false;
//限制插入必须是在数组下标范围内包含尾部插入。
if(index > this.index+1 || index < 0) return false;
//插入时原数组容量满了,触发扩容。
if(this.index+1 == objs.length) {
this.capacity();
}
//尾插
if(this.index+1 == index) {
objs[index] = obj;
this.index++;
return true;
}
//复制原数组到新数组然后对预留的插入位置插入。
Object[] newObjs = new Object[objs.length];
System.arraycopy(objs, 0, newObjs, 0, index);
System.arraycopy(objs, index, newObjs, index+1, objs.length-(index+1));
this.objs = newObjs;
objs[index] = obj;
this.index++;
return true;
}
public int get(Object obj) {
//遍历获取
if(obj == null || this.index == -1) return -1;
for(int i=0;i<=index;i++) {
if(obj.equals(objs[i])) {
return i;
}
}
return -1;
}
public boolean remove(Object obj) {
if(obj == null || this.index == -1) return false;
for(int i=0;i<=index;i++) {
if(obj.equals(objs[i])) {
//这里刚刚学集合没有考虑到先找到目标出循环再处理。不应该在循环内部直接操作。
//创建新数组
Object[] newObjs = new Object[objs.length];
//处理这里自己画图操作容易看清楚是删除哪个下标。不然容易删错。
System.arraycopy(objs, 0, newObjs, 0, i);
System.arraycopy(objs, i+1, newObjs, i, objs.length-i-1);
objs[index] = null;
this.objs = newObjs;
index--;
return true;
}
}
return false;
}
}