1.ArrayList、LinkedList、Vector的异同与使用场景
一般来说,ArrayList与Vector都是使用数组来存储,LinkedList是使用双向链表进行存储,所以,ArrayList和Vector查找元素比较快,因为数组可以直接根据位置进行定位,而双向链表还需要根据链表头或者链表尾进行遍历查询。而在插入元素时,一般来说LinkedList比较快,因为双向链表只需要找到插入位置的前一个元素,然后进行插入即可(当然需要更改后一个元素的前驱),而因为数组是确定大小的,在尾部添加元素时,ArrayList与Vector都需要确认一下数组是否充足,如果不充足,还需要将数组进行扩大,再将原先的元素重新copy进去,而在中间插入元素时,ArrayList与Vector,ArrayList与Vector也需要确认一下数组是否充足,然后将插入位置的元素整体后移,所以一般来说,在插入元素时,LinkedList更快一些。
2.Java ArrayList与LinkedList源码分析与比较
(1) 源码分析:
(2) 什么之后用ArrayList,什么时候用LinkedList:
ArrayList与LinkedList实现了List接口,那么我们应该什么时候使用ArrayList,什么时候使用LinkedList呢?
ArrayList的优势在于直接根据获取的位置找到数组的位置,然后获取存储在数组中的对象。但缺点是使用数组进行储存,当数组空间不够时,还需要新建更大容量的数组,并将原先的数据全部拷贝过去。而且在插入、删除数据时,由于是使用数组储存,需要将插入、删除位置及之后的所有数据都移动。
LinkedList的优势在与有多少对象就新建多少节点,不会造成空间浪费,而且在插入、删除时可以不用移动后面的数据。但缺点在于每次得到指定位置的节点时,都需要从头部或者从尾部进行遍历。
所以,当程序需要大量的插入、删除数据,或在头部、尾部插入数据时,使用LinkedList。如果是需要大量的获取指定位置的数据,那么使用ArrayList。
3.ArrayList、Vector源码分析与比较
(1) 比如add方法:
ArrayList:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
Vector:
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
可以看到,ArrayList与Vector差别不大,不过Vector的add方法是线程安全的。
(2) 在增加数组大小的grow()方法中
ArrayList:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
Vector:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
可以看到 ArrayList 一般是增加自己的一半,而Vector是增加自己的一倍。
java8中list的源码:
首先,List是一个接口,是一个继承了Collection接口的接口。。。并定义扩展了自己的方法。
打开java8中List的源码,可以看到,它重写了许多父类的方法。普通的abstract方法平常用的多,暂时不解析。在源码中看到这样一个方法:
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
这个方法之前也见过,但是不是List的,是Collections.replaceAll()方法;
import java.util.*;
public class Main {
public static void main(String[] args) {
List list = Arrays.asList("one Two three Four five six one three Four".split(" "));
System.out.println("List :"+list);
Collections.replaceAll(list, "one", "hundrea");
System.out.println("replaceAll: " + list);
}
}
以上代码运行输出结果为:
List :[one, Two, three, Four, five, six, one, three, Four]
replaceAll: [hundrea, Two, three, Four, five, six, hundrea, three, Four]
接下来是List.replaceAll()的实现;
import java.util.function.*;
class MyOperator<T> implements UnaryOperator<T>{
T varc1;
public T apply(T varc){
return varc1;
}
}
import java.util.*;
public class test {
public static void main(String[] args) {
ArrayList<String> color_list;
MyOperator<String> operator;
color_list = new ArrayList<> ();
operator = new MyOperator<> ();
operator.varc1 = "White";
// use add() method to add values in the list
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
System.out.println("List of Colors");
System.out.println(color_list);
// Replace all colors with White color
color_list.replaceAll(operator);
System.out.println("Color list, after replacing all colors with White color :");
System.out.println(color_list);
}
}
//输出结果
List of Colors
[White, Black, Red, White, Yellow, White]
Color list, after replacing all colors with White color :
[White, White, White, White, White, White]
发现与以往用的方法很大不同,它真的是全部替换。
最后,List源码并不能看出什么重要的东西,主要还是去它的实现类里去看。