Set中的数据对象没有顺序且不可以重复;
List中的数据对象有顺序且可以重复;
ArrayList与LinkedList的区别就是数组与链表的区别,效率高,线程不安全;
Vector底层也是数组,线程安全,但是效率低。
每个ArrayList实例的初始容量,默认为10,随着ArrayList元素的增加,它的容量也会增长,每次添加新的元素,都会对ArrayList实例进行容量检查,判断是否需要扩容,扩容是将旧数组的数据拷贝到一个大容量的新数组中。
/**
*
*/
package com.sunlei;
/**
*@author 作者:sunlei
*@version 创建时间:2018年2月28日下午7:50:53
*说明
*/
public class MyArrayList {
private Object[] elementData;
private int size;
public MyArrayList() {
this(10);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public MyArrayList(int initialCapacity) {
if(initialCapacity < 0 ) {
try {
throw new Exception();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
elementData = new Object[initialCapacity];
}
//下标越界检查
public void rangeCheckForAdd(int index) {
if(index < 0 || index >= size) {
try {
throw new Exception();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//数组扩容
public void ensureCapacityInternal() {
if(size == elementData.length) {
Object[] newArray = new Object[size*2+1];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
elementData = newArray;//注意要将目标数组重新赋给原数组
}
}
public void add(Object obj) {
ensureCapacityInternal();
elementData[size++] = obj;
}
public void add(int index,Object obj) {
rangeCheckForAdd(index);
ensureCapacityInternal();
System.arraycopy(elementData, index, elementData, index+1, size - index);
elementData[index] = obj;
size++;//注意要将size++
}
public Object get(int index) {
rangeCheckForAdd(index);
return elementData[index];
}
public void remove(int index) {
rangeCheckForAdd(index);
int numMoved = size - index - 1;
if(numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null;
}
public void remove(Object obj) {
for(int i=0;i<size;i++) {
if(get(i).equals(obj)) {
remove(i);
}
}
}
public void set(int index,Object obj) {
rangeCheckForAdd(index);
Object oldValue = elementData[index];
elementData[index] = obj;
}
public static void printArrayList(MyArrayList list) {
for(int i=0;i<list.size();i++) {
System.out.print(list.get(i)+" ");
}
System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MyArrayList list = new MyArrayList(3);
list.add("111");
list.add("222");
list.add("333");
list.add("444");
System.out.println(list.size());
System.out.println(list.isEmpty());
printArrayList(list);
list.remove(2);
printArrayList(list);
list.remove("111");
printArrayList(list);
list.set(1, "555");
printArrayList(list);
list.add(0, "666");
printArrayList(list);
System.out.println(list.size());
}
}
1.在方法的带入参数中出现下边时,都要对下标做范围检查,防止下标越界。
2.数组扩容,采用的是扩大到原来数组大小的2倍再加1,与JDK源码里面的有不同。
3.数组类容拷贝,采用的是System.arraycopy(src, srcPos, dest, destPos, length)方法
src表示的是原数组;
srcPos表示原数组中开始截取的地方;
dest表示目标数组,即新数组;
destPos表示目标数组中开始放的地方;
length表示截取的长度。