Source code analysis based on Arraylist's add(int index, E object) method and time-consuming comparison with Linkedlist's access data

Keywords: ButterKnife

  • First, compare the speed of Arraylist and Linkedlist accessing data

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_content_detail);
      ButterKnife.bind(this);
    
      System.out.println("ArrayList Add to" + N + "Time consuming:" + addElements(new ArrayList()));
      System.out.println("LinkedList Add to" + N + "Time consuming:" + addElements(new LinkedList()));
    
      List list1 = addList(new ArrayList<>());
      List list2 = addList(new LinkedList<>());
      System.out.println("ArrayList lookup" + N + "Time consuming:" + readList(list1));
      System.out.println("LinkedList lookup" + N + "Time consuming:" + readList(list2));
    
    }
private long addElements(List list) {
    long start = System.currentTimeMillis();
    for (int i = 0; i < N; i++) {
        list.add(0, "" + i);
    }
    return System.currentTimeMillis() - start;
  }

private long readList(List list) {
    long start = System.currentTimeMillis();
    for (int i = 0, j = list.size(); i < j; i++) {
        list.get(i);
    }
    return System.currentTimeMillis() - start;
}

private List addList(List list) {
    for (int i = 0; i < N; i++) {
        list.add(0, "" + i);
    }
    return list;
}

Output results:

03-28 15:09:30.321 14873-14873/com.amazingokc.zhihucolumn I/System.out: ArrayList adds 50,000 time-consuming items: 2249
 03-28 15:09:30.551 14873-14873/com.amazingokc.zhihucolumn I/System.out: LinkedList adds 50,000 time-consuming items: 233
 03-28 15:09:32.911 14873-14873/com.amazingokc.zhihucolumn I/System.out: ArrayList finds 50,000 pieces of time-consuming:
03-28 15:09:45.451 14873-14873/com.amazingokc.zhihucolumn I/System.out: LinkedList Find 50,000 Time-consuming: 12540

You can see that each has its advantages and disadvantages.

Actually from Linkedlist Source Code As you can see, for a unified linked list, adding data from a specified location takes almost the same time as getting data. Change the above code slightly.

private long addElements(List list) {

    for (int i = 0; i < 40000; i++) {
        list.add(0, "" + i);
    }
    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
        list.add(20000, "" + i);
    }
    return System.currentTimeMillis() - start;
}

private long readList(List list) {
    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
        list.get(20000);
    }
    return System.currentTimeMillis() - start;
}

Output:

03-28 16:24:37.178 23163-23714/com.amazingokc.zhihucolumn I/System.out: ArrayList adds 10,000 time-consuming items: 410
 03-28 16:24:41.658 23163-23714/com.amazingokc.zhihucolumn I/System.out: LinkedList adds 10,000 time-consuming items: 4321
 03-28 16:24:43.928 23163-23714/com.amazingokc.zhihucolumn I/System.out: ArrayList finds 10,000 pieces of time-consuming:1
 03-28 16:24:48.228 23163-23714/com.amazingokc.zhihucolumn I/System.out: LinkedList Find 10,000 Time-consuming: 4298

The difference between the previous time-consuming value is so large, because the list is slowly growing at the beginning, the list has always been the maximum when reading, the total time of random traversal of the list is different.

  • 1 Arraylist add(int index, E object) method

    Arraylist's add(int index, E object) method is time-consuming, which is determined by the structure of arrays. Arrays are consecutively stored. When manipulating data in arrays, data in corresponding positions can be accessed directly according to the offset from the first address. However, if you want to insert an element at any position in the data group, you need to group the following elements backward first. Move one bit to make room for it. On the contrary, linked lists are stored discretely, so when inserting a data, you only need to apply for a new space, and then make a modification of the connection relationship between them. But obviously, when looking for a data on the linked list, you have to go through it one by one. Look at the source code implementation:
 /**
 *Inserts the specified object into this {@code ArrayList} at the specified
 * location. The object is inserted before any previous element at the
 * specified location. If the location is equal to the size of this
 * {@code ArrayList}, the object is added at the end.
 *
 * @param index
 *            the index at which to insert the object.
 * @param object
 *            the object to add.
 * @throws IndexOutOfBoundsException
 *             when {@code location < 0 || location > size()}
 */
@Override public void add(int index, E object) {
    Object[] a = array;
    int s = size;
    if (index > s || index < 0) {
        throwIndexOutOfBoundsException(index, s);
    }

    if (s < a.length) {
        System.arraycopy(a, index, a, index + 1, s - index);
    } else {
        // assert s == a.length;
        Object[] newArray = new Object[newCapacity(s)];
        System.arraycopy(a, 0, newArray, 0, index);
        System.arraycopy(a, index, newArray, index + 1, s - index);
        array = a = newArray;
    }
    a[index] = object;
    size = s + 1;
    modCount++;
}

The first arraycopy copies the index elements from zero to zero in the new Array, and the second arraycopy releases the other elements of the original array a into the index + 1 position of the new Array. At this time, the index position of the new Array does not contain any elements, which is me. We need to add the location of the element, a[index] = object; the addition is completed. So every time an element is added, the element of the original array will be copied. The method of adding (E object) is to add elements at the tail, just put all the complex elements in front of the new array, and then add an element at the tail of the new number. The speed should be relatively faster. The source code principle of deleting remove(int index) is basically similar, which is why Arraylist's add-delete operation is time-consuming.

Posted by newbieaj on Sun, 16 Dec 2018 22:33:04 -0800