Java 集合之 List 详解与源码分析

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源码并不能看出什么重要的东西,主要还是去它的实现类里去看。
 


 

猜你喜欢

转载自blog.csdn.net/qfc8930858/article/details/87598100