(所有源码均在:https://github.com/zongzhec/JavaPractise)
目录
容器 - 自定义数组【附源码】
概要
学习一个API的最好办法,就是尝试自己写一个。现在我们尝试自己写一个ArrayList,并实现增删查改的功能。
目标
在写功能之前,先把我们调用的方式定义好,并在心中盘算应该得到的结果。(其实就是一种BDD)
显然此次的目标是增删查改,那么先把调用的方式写好,如下。
源码
package zongzhe.java_basic.data_structure;
public class CustomArrayListDemo {
public static void main(String[] args) {
MyArrayList myList = new MyArrayList();
// 增:自定义容器必须可以添加元素
myList.add("Zongzhe");
myList.add("Czz");
myList.add(null);
// 删:自定义容器必须可以删除元素
myList.remove(null);
// 查:自定义容器必须可以查看元素数量
System.out.println("size: " + myList.size());
// 查:必须可以以数组的形式返回所有有效元素
Object[] all = myList.toArray();
for (Object obj : all) {
System.out.println("element: " + obj);
}
// 查:必须可以返回指定位置的元素
System.out.println("get(1): " + myList.get(1));
// 改:自定义容器必须可以修改元素
myList.set("Czz", "Czzzz");
// 需要可以查找obj在当前容器中的索引,如果没有,返回-1
System.out.println("indexOf(): " + myList.indexOf("Czz"));
}
}
功能实现
在知道怎么用之后,剩下的就是把功能补齐了。特别要注意以下几点:
- 增 - 容量问题:新加的元素是不是超出了边界?如果是,怎么扩容?
- 查 - 边界问题:查找的元素是否越界?如果是,如何处理?
- 查 - 空值问题:如果查找的对象是空值怎么办?equals() 方法怎么处理?
源码
package zongzhe.java_basic.data_structure;
import java.util.Arrays;
/**
* 实现自定义容器
*/
public class MyArrayList {
private Object[] data; // 不知道装什么对象,所以用Object 来承载
private int total; // 表示当前容器的大小,用于扩容和其他检查
public MyArrayList() {
data = new Object[10]; // 默认初始化大小
}
public void add(Object obj) {
// 先检查容器是否已满
if (total >= data.length) {
data = Arrays.copyOf(data, data.length * 2);
}
// 填入数据
data[total++] = obj;
}
public void remove(Object obj) {
// 先查找位置
int index = indexOf(obj);
// 删除
if (index != -1) {
System.arraycopy(data, index + 1, data, index, total - index - 1);
data[--total] = null;
}
}
public int size() {
return total;
}
public void set(Object oldObj, Object newObj) {
int index = indexOf(oldObj);
if (index != -1) {
data[index] = newObj;
}
}
public Object[] toArray() {
return Arrays.copyOf(data, total);
}
public Object get(int index) {
if (index < 0 || index >= total) {
throw new IndexOutOfBoundsException("index outOfBound: " + index);
}
return data[index];
}
public int indexOf(Object obj) {
int index = -1;
for (int i = 0; i < total; i++) { // 思考:此处的total能不能换成data.length()?
if ((obj == null && data[i] == null) || (obj.equals(data[i]))) { // null 也是合法元素
index = i;
break;
}
}
return index;
}
}