Java Collections series (two): use ArrayList, LinkedList, Vector and differences

This blog mainly on three of the List interface implementation class ArrayList difference between LinkedList, using the methods of Vector and three.

1. ArrayList use

ArrayList List interface is the most common implementation class, achieved by internal array, so its advantages are suitable for random search and traversal, the disadvantage is not suitable for insertion and deletion.

ArrayList class declaration code is as follows:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    ......
}

1.1 Adding elements

Use ArrayList added element has the following two overloads:

boolean add(E e);
    
void add(int index, E element);

boolean add(E e);It is to add elements to the end of the collection,

void add(int index, E element);It is to add elements to the specified index position (the index starting from 0).

Use as follows:

List<String> platformList = new ArrayList<>();

// 添加元素
platformList.add("博客园");
platformList.add("掘金");
platformList.add("微信公众号");

// 添加重复元素,会添加成功,因为List支持添加重复元素
platformList.add("博客园");
platformList.add("掘金");


platformList.add(3, "个人博客");

1.2 Gets the element

Get the ArrayList at the specified index of elements of the methods are as follows:

System.out.println("索引为3的元素为:" + platformList.get(3));

If the specified index exceeds the maximum index of the collection, such as platformList.get(6)will throw an exception java.lang.IndexOutOfBoundsException:

1.3 Get number of the sets of elements

Get the number of elements of the ArrayList methods are as follows:

System.out.println("platformList的元素个数为:" + platformList.size());

1.4 Removing elements

ArrayList delete elements using the following two overloads:

E remove(int index);

boolean remove(Object o);

E remove(int index);Is to remove the collection at the specified index of the element, boolean remove(Object o);it is to delete the specified element in the collection.

Use as follows:

// 指定索引删除重复的元素 "博客园" "掘金"
platformList.remove(4);
platformList.remove(4);
// 删除指定元素 "个人博客"
platformList.remove("个人博客");

1.5 modify elements

ArrayList modifying elements at the specified index value using the following method:

platformList.set(0, "博客园:https://www.cnblogs.com/zwwhnly/");
platformList.set(1, "掘金:https://juejin.im/user/5c7ce730f265da2dca388167");
platformList.set(2, "微信公众号:申城异乡人");

1.6 is determined whether the set is empty

ArrayList is empty is determined whether to use the following:

System.out.println("isEmpty:" + platformList.isEmpty());

1.7 traversing element (Frequently Asked Interview)

Traverse the elements of the ArrayList mainly in the following three ways:

  1. Iterates over
  2. for loop
  3. foreach loop

Use as follows:

System.out.println("使用Iterator遍历:");
Iterator<String> platformIterator = platformList.iterator();
while (platformIterator.hasNext()) {
    System.out.println(platformIterator.next());
}

System.out.println();
System.out.println("使用for循环遍历:");
for (int i = 0; i < platformList.size(); i++) {
    System.out.println(platformList.get(i));
}

System.out.println();
System.out.println("使用foreach遍历:");
for (String platform : platformList) {
    System.out.println(platform);
}

1.8 Empty collection

Empty ArrayList method using all the elements are as follows:

platformList.clear();

1.9 Full Sample Code

Some, complete code explained above is as follows:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();

    // 添加元素
    platformList.add("博客园");
    platformList.add("掘金");
    platformList.add("微信公众号");

    // 添加重复元素,会添加成功,因为List支持添加重复元素
    platformList.add("博客园");
    platformList.add("掘金");


    platformList.add(3, "个人博客");

    System.out.println("索引为3的元素为:" + platformList.get(3));
    System.out.println("platformList的元素个数为:" + platformList.size());

    // 指定索引删除重复的元素 "博客园" "掘金"
    platformList.remove(4);
    platformList.remove(4);
    // 删除指定元素 "个人博客"
    platformList.remove("个人博客");

    System.out.println("platformList的元素个数为:" + platformList.size());

    platformList.set(0, "博客园:https://www.cnblogs.com/zwwhnly/");
    platformList.set(1, "掘金:https://juejin.im/user/5c7ce730f265da2dca388167");
    platformList.set(2, "微信公众号:申城异乡人");

    System.out.println("isEmpty:" + platformList.isEmpty());

    System.out.println("使用Iterator遍历:");
    Iterator<String> platformIterator = platformList.iterator();
    while (platformIterator.hasNext()) {
        System.out.println(platformIterator.next());
    }

    System.out.println();
    System.out.println("使用for循环遍历:");
    for (int i = 0; i < platformList.size(); i++) {
        System.out.println(platformList.get(i));
    }

    System.out.println();
    System.out.println("使用foreach遍历:");
    for (String platform : platformList) {
        System.out.println(platform);
    }

    System.out.println();

    // 清空集合
    platformList.clear();
    System.out.println("isEmpty:" + platformList.isEmpty());
}

The output is:

3 index elements are: personal blog

PlatformList number of elements is: 6

PlatformList number of elements is: 3

isEmpty:false

Use Iterator to traverse:

Park blog: https://www.cnblogs.com/zwwhnly/

Nuggets: https://juejin.im/user/5c7ce730f265da2dca388167

Micro-channel public number: Shanghai Stranger

Use for loop iterates:

Park blog: https://www.cnblogs.com/zwwhnly/

Nuggets: https://juejin.im/user/5c7ce730f265da2dca388167

Micro-channel public number: Shanghai Stranger

Use foreach traversal:

Park blog: https://www.cnblogs.com/zwwhnly/

Nuggets: https://juejin.im/user/5c7ce730f265da2dca388167

Micro-channel public number: Shanghai Stranger

isEmpty:true

2. LinkedList use

List LinkedList interface implementation class is used internally linked list structure to store data, so it is an advantage for dynamically inserting and removing elements, the disadvantage is found randomly and traverse slower.

LinkedList class declaration code is as follows:

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
}

Use ArrayList LinkedList class and essentially the same, only the modifications to the code declared at:

List<String> platformList = new LinkedList<>();

3. Vector Use

Vector also List interface implementation class, is realized by the internal array.

Vector class code is declared as follows:

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
}

The difference is that the ArrayList, Vector is thread-safe, that only one thread at a time can write Vector, avoid multi-threading while writing the inconsistency caused. But it also resulted in the disadvantage of Vector: implement additional spending required synchronization of threads, so its speed will be slower than some of the ArrayList.

Vector is ArrayList can be considered in a multithreaded environment implementation version.

Therefore, the use of Vector class ArrayList and essentially the same, only the modifications to the code declared at:

List<String> platformList = new Vector<>();

Due to the support thread synchronization, so many ways Vector class has synchronized keyword as follows:

public synchronized boolean isEmpty() {
    return elementCount == 0;
}

public synchronized int size() {
    return elementCount;
}

public synchronized void addElement(E obj) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;
}

4. ArrayList, the difference between LinkedList, Vector's (Frequently Asked Interview)

Note: The following code uses the JDK version 1.8.0_191

4.1 similarities

ArrayList, LinkedList, Vector implements List interface, so it is similar to the use, by the above example can be found this.

4.2 difference

But ArrayList, different LinkedList, Vector's internal implementation, it leads there is a difference between them.

4.2.1 Storage Structure

ArrayList and the Vector is array-based implementation, LinkedList is implemented based on a doubly linked list.

This also led to ArrayList for random search and traversal, while LinkedList suitable for dynamic insertion and deletion of elements.

About arrays and doubly linked lists, not to explain here, follow-up will write a separate article summary.

4.2.2 Thread safety

ArrayList and LinkedList are not thread-safe, Vector is thread-safe.

Vector ArrayList can be seen in a multithreaded environment of another implementation, which also led to efficiency is not high ArraykList Vector and LinkedList.

If you are using ArrayList or LinkedList in a concurrent environment, you can call synchronizedList () method of the Collections class:

Collections.synchronizedList(platformList);

4.2.3 expansion mechanism

ArrayList and Vector are using an array of type Object to store data, ArrayList default capacity is 0, the default capacity is 10 Vector.

Empty rumor, we look at using the example ArrayList:

List<String> strArrayList = new ArrayList<>();

for (int i = 0; i < 20; i++) {
    strArrayList.add(String.valueOf(i));
}

Source ArrayList constructor would be:

transient Object[] elementData;

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

Look at sample using the Vector:

List<String> strVector = new Vector<>();

for (int i = 0; i < 30; i++) {
    strVector.add(String.valueOf(i));
}

Source Vector constructor would be:

protected Object[] elementData;
protected int capacityIncrement;

public Vector() {
    this(10);
}

public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}

public Vector(int initialCapacity, int capacityIncrement) {
      super();
      if (initialCapacity < 0)
          throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
      this.elementData = new Object[initialCapacity];
      this.capacityIncrement = capacityIncrement;
}

When the elements are added to both types, if the capacity is not enough, the expansion will be performed, the nature of the expansion is to produce a new array, copying the original data array into a new array, and then add a new element to the new array, the method is used Arrays.copyOf()in which the capacity after expansion is 1.5 times ArrayList before, Vector default capacity after the expansion in the case of two times before .

ArrayList still use the above examples:

List<String> strArrayList = new ArrayList<>();

for (int i = 0; i < 20; i++) {
    strArrayList.add(String.valueOf(i));
}

After the execution List<String> strArrayList = new ArrayList<>();, the case strArrayList capacity is 0,

And then when the addition of the first element, strArrayList expansion capacity is the capacity of 10,

When the addition of 11 elements, strArrayList expansion capacity is the capacity of 15,

When the addition of 16 elements, strArrayList expansion capacity is the capacity of 22,

If required expansion, the expansion will turn 33 -> 49.

ArrayList look at the source code, I understand why this expansion:

private static final int DEFAULT_CAPACITY = 10;

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

private static int calculateCapacity(Object[] elementData, int minCapacity) {
     if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
         return Math.max(DEFAULT_CAPACITY, minCapacity);
     }
     return minCapacity;
}

private void ensureExplicitCapacity(int minCapacity) {
     modCount++;

     // overflow-conscious code
     if (minCapacity - elementData.length > 0)
         grow(minCapacity);
}

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);
}

Code is the core int newCapacity = oldCapacity + (oldCapacity >> 1);, so that the capacity after expansion is 1.5 times ArrayList before.

Vector look at the example above:

List<String> strVector = new Vector<>();

for (int i = 0; i < 30; i++) {
    strVector.add(String.valueOf(i));
}

After the execution List<String> strVector = new Vector<>();, the case 10 is strVector capacity,

When the addition of 11 elements, strVector expansion capacity is the capacity of 20,

When the addition of 21 elements, strVector expansion capacity is the capacity of 40,

If you also need expansion, will be followed by expansion to 80 -> 160.

Vector look at the source code, you understand why this expansion:

public synchronized void addElement(E obj) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;
}

private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

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);
}

The core code is int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);, the capacity expansion at Vector after the default is 2 times before.

4.2.4 Efficiency

ArrayList random search and traversal efficiency will be higher, but the efficiency of dynamic insertion and deletion of elements will be lower.

Insert and delete elements LinkedList dynamic efficiency will be higher, but a random search and traverse the efficiency will be lower.

If you need to operate a collection of elements in a multi-threaded, it is recommended to use Vector, otherwise, it is recommended to use ArrayList.

The source and reference

Differences and realize the principle of ArrayList, LinkedList, Vector's

Java depth - depth understanding of the Java Collections

Advanced Java (forty-six) Description of ArrayList, Vector and LinkedList similarities and differences

6. Finally

Play a little advertising, welcomed the focus on micro-channel scan code number public: "Shanghai is a stranger" on a regular basis to share Java technology dry goods, so that we progress together.

Guess you like

Origin www.cnblogs.com/zwwhnly/p/11265599.html