1.ArrayList的底层实现:长度可动态增长的数组,即顺序表
优点:按索引查询效率高
缺点:插入,删除效率低;
按内容查询效率低;
必须提前分配固定数量的空间,如果存储元素少,可能导致空闲浪费。
特点:在内存中分配连续的空间,只存储数据,不存储地址信息。位置就隐含着地址。
有序,不唯一
注意;ArrayList通过无参的构造方法创建对象时,jdk1.7初始长度为10;jdk1.8初始长度为0,在第一次添加元素时就需要进行扩容;当以后容量不足时,每次扩容50%;·
2.手写ArrayList源码:
(1)定义List接口,该接口包含了get,add,toString,indexOf等方法,这些方法都将被ArrayList类实现
public interface List {
public int size();// 返回线性表的大小,即数据元素的个数。
public Object get(int i); // 返回线性表中序号为 i 的数据元素
public boolean isEmpty();// 如果线性表为空返回 true,否则返回 false。
public boolean contains(Object e); // 判断线性表是否包含数据元素 e
public int indexOf(Object e); // 返回数据元素 e 在线性表中的序号
public void add(int i, Object e); // 将数据元素 e 插入到线性表中 i 号位置
public void add(Object e);// 将数据元素 e 插入到线性表末尾
public boolean addBefore(Object obj, Object e); // 将数据元素 e 插入到元素 obj 之前
public boolean addAfter(Object obj, Object e); // 将数据元素 e 插入到元素 obj 之后
public Object remove(int i); // 删除线性表中序号为 i 的元素,并返回之
public boolean remove(Object e); // 删除线性表中第一个与 e 相同的元素
public Object replace(int i, Object e); // 替换线性表中序号为 i 的数据元素为 e,返回原数据元素
public Iterator iterator(); //迭代List
}
(2)自定义一个异常类(继承RuntimeException接口)
public class IndexOutOfBoundsException extends RuntimeException {
public IndexOutOfBoundsException() {}
public IndexOutOfBoundsException(String message) {
super(message);}
}
(3)定义一个Iterator接口,其包含hasNext,next方法;用于ArrayList所创建对象的遍历迭代
public interface Iterator<T> {
public boolean hasNext();//判断是否存在下一个元素
public T next();//得到下一个元素
}
(4)定义一个ArrayList,实现List接口中的方法
import java.util.Arrays;
public class ArrayList implements List {
private Object[] elementData;//ArrayList底层是一个长度可以动态增长的数组elementData是数组的引用
private int size;//集合中元素的个数,不是数组空间中的容量
public ArrayList() {//默认的长度
this(10);//jdk1.7默认长度为10
}
public ArrayList(int initialCapacity) {//可以自定义初始长度
elementData = new Object[initialCapacity];
}
@Override
public int size() {
return size;
}
@Override
public Object get(int i) {
if (i < 0 || i >= size) {
throw new IndexOutOfBoundsException("数组索引越界: " + i);
}
return elementData[i];
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean contains(Object e) {
return indexOf(e) >= 0;
}
@Override
public int indexOf(Object e) {
int index = -1;
if (e == null) {
for (int i = 0; i < size; i++) {
if (e == elementData[i]) {
index = i;
break;
}
}
} else {
for (int i = 0; i < size; i++) {
if (e.equals(elementData[i])) {
index = i;
break;
}
}
}
return index;
}
@Override
public void add(int index, Object e) {
if (elementData.length == size) {//如果数组已满,需要扩容
grow();
}
for (int i = size; i > index; i--) {
elementData[i] = elementData[i - 1]; //从前往后移动一个位置
}
elementData[index] = e; //添加元素到i个位置
size++;
}
@Override
public void add(Object e) {
if (elementData.length == size) { //如果数组已满,需要扩容
grow();
}
elementData[size] = e;//添加元素到最后
size++;
}
private void grow() {//扩容方法
// //1.新创建一个更大容量的数组
// int oldCapacity = elementData.length;
// int newCapacity = (oldCapacity + (oldCapacity >> 1));
// //Object newAtrray = new Object[elementData.length + elementData.length >> 1];
// Object[] newArray = new Object[newCapacity];
// // 2.将原来数组的元素拷贝到新数组中,索引对应
// for (int i = 0; i < elementData.length; i++) {
// newArray[i] = elementData[i];
// }
// //3.成员变量elementData指向扩容后的新数组
// elementData = newArray;
elementData = Arrays.copyOf(elementData, (elementData.length + (elementData.length >> 1)));//简略写法
}
@Override
public boolean addBefore(Object obj, Object e) {
return false;
}
@Override
public boolean addAfter(Object obj, Object e) {
return false;
}
@Override
public Object remove(int i) {
return null;
}
@Override
public boolean remove(Object e) {
return false;
}
@Override
public Object replace(int i, Object e) {
return null;
@Override
public Iterator iterator() {
return new Itr();
}
private class Itr<T> implements Iterator<T> {
int cursort = 0;//指向当前元素 默认第一个(索引是0)
@Override
public boolean hasNext() {
return cursort != size;
}
@Override
public T next() {
if (cursort >= size) {
throw new RuntimeException("出错啦");
}
return (T) elementData[cursort++];
}
}
public String toString() {
StringBuilder builder = new StringBuilder("[");
for (int i = 0; i < size; i++) {
builder.append(elementData[i] + ",");
}
if (size > 0) {//去掉多余的逗号
builder.deleteCharAt(builder.length() - 1);
}
builder.append("]");
return builder.toString();
}
}
5:创建一个测试类
public class TestArrayList {
public static void main(String[] args) {
java.util.List list2 = new java.util.ArrayList();
List list = new ArrayList();//创建线性顺序表
//向末尾添加元素
list.add("11111");
list.add("aaaaa");
list.add("bbbbb");
list.add("33333");
list.add(null);
list.add(3, "AAAAA");
System.out.println(list.size());
System.out.println(list.isEmpty());
System.out.println(list.get(3));
System.out.println(list.contains("5555"));
System.out.println(list.indexOf(null));
System.out.println(list.toString());
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String elem = it.next();
System.out.println(elem);
}
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
}
}
运行结果