ArrayList实现原理及常用的添加查找方法
ArrayList是集合里面的一种,该集合实现的是List集合接口,而List集合接口继承的Collection的接口,但由于实现的是List集合接口所以ArrayList的特点为有序,但是不唯一,里面的值可以重复,优点是查询很快,下面我们来创建一个ArrayList集合
ArrayList<String> list = new ArrayList<String>();//不定义长度
ArrayList<String> list1 = new ArrayList<String>(5);//定义长度
接下来我们按住CTRL然后点击类名去看它的创建方式
private transient Object[] elementData;
public ArrayList() {
this(10);
}
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
this.elementData = new Object[initialCapacity];
}
我们可以看到,在ArrayList里面有一个私有的数组;当我们创建集合并没有定义长度的时候,它会自动传一个10给有参构造方法然后将elementData重新创建并给它10的长度。
首先我们可以看下这两个集合的长度;
System.out.println(list.size());//未定义宽度的集合宽度
System.out.println(list1.size());//定义了宽度的集合宽度
输出结果如下
private int size;//默认0
public int size() {
return size;
}
可以看到size一开始默认为0,所以直接输出的0;
添加方法
list.add("猪嘤");//先给没有定义长度的集合添加数据
list.add(1,"蠢猪嘤");//使用另一种方式给定义了长度的集合添加数据
我们会发现,第二个添加数据的时候报错了
接下来打开add() 方法看下
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,size - index);
elementData[index] = element;
size++;
}
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
第一个**add()方法首先传进去参数以后先进入到ensureCapacity(1)**方法,然后先把原来的数组长度10用一个变量储存
然后再去把原来数组长度去和传进来的参数进行比较,为false就直接跳出方法,然后直接给原来数组的第一个位置赋值再
让size变成1;
第二个add() 方法把1和要储存的值传进去以后先和全局变量size进行对比然后1>0所以直接抛出异常,由此可以得出,
使用第二种add() 方法进行添加的时候添加的位置不能大于原来size的值,也就是集合里面的个数。
查找方法
indexof();
首先我们先往第一个list 集合里面添加一些测试数据
list.add("嘤嘤嘤");
list.add("消嘤器");
list.add(null);
System.out.println(list.indexOf(null));
System.out.println(list.indexOf("嘤嘤嘤"));
输出结果如下
接着去看下indexOf()的源码
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
可以看到当我们找到了参数以后,就会返回该参数所在的下标,如果没找到就会返回-1,lastIndexOf()原理也是这样;