(Android) Java for循環每次都通過list.size()和 string.length()獲取大小是否消耗性能?

前言

有人說在for循環之前用一個局部變量先獲取到list.size()、str.length(),然後在for循環的判斷條件裏通過這個局部變量替換list.size()、str.length()會節省數據計算的時間。事實真的是這樣嗎?下面就爲大家解答這個問題。

說明:此文章針對Android SDK 進行說明。

List.size()

首先我們看一下List接口,我們知道.size()方法是List接口的一個方法,返回一個int類型的值。

public interface List<E> extends Collection<E> {
	//省略部分代碼...
	
    /**
     * Returns the number of elements in this {@code List}.
     *
     * @return the number of elements in this {@code List}.
     */
    public int size();
    
	//省略部分代碼...
}

接口中的方法都是沒有具體實現的,我們下面看一下List的實現類ArrayList(LinkList也一樣,這裏講ArrayList)。我們先看下ArrayList類中的size()方法是如何實現的:

public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess {

	//省略部分代碼...
	/**
     * Returns the number of elements in this {@code ArrayList}.
     *
     * @return the number of elements in this {@code ArrayList}.
     */
    @Override public int size() {
        return size;
    }
    //省略部分代碼...
}

我們看到ArrayList裏的size()方法直接return了一個size,通過查看發現size是ArrayList類中的一個int類型的成員變量,代表list結合中的元素數量。

    /**
     * The number of elements in this list.
     */
    int size;

通過跟蹤size變量發現在ArrayList類中的add,remove方法中都會動態改變size的大小。

 /**
     * Adds the specified object at the end of this {@code ArrayList}.
     *
     * @param object
     *            the object to add.
     * @return always true
     */
    @Override public boolean add(E object) {
        Object[] a = array;
        int s = size;
        if (s == a.length) {
            Object[] newArray = new Object[s +
                    (s < (MIN_CAPACITY_INCREMENT / 2) ?
                     MIN_CAPACITY_INCREMENT : s >> 1)];
            System.arraycopy(a, 0, newArray, 0, s);
            array = a = newArray;
        }
        a[s] = object;
        size = s + 1; // 添加元素size增加
        modCount++;
        return true;
    }
...
    /**
     * Removes the object at the specified location from this list.
     *
     * @param index
     *            the index of the object to remove.
     * @return the removed object.
     * @throws IndexOutOfBoundsException
     *             when {@code location < 0 || location >= size()}
     */
    @Override public E remove(int index) {
        Object[] a = array;
        int s = size;
        if (index >= s) {
            throwIndexOutOfBoundsException(index, s);
        }
        @SuppressWarnings("unchecked") E result = (E) a[index];
        System.arraycopy(a, index + 1, a, index, --s - index); //刪除元素 size--
        a[s] = null;  // Prevent memory leak
        size = s;
        modCount++;
        return result;
    }

通過上述代碼我們知道通過ArrayList中的.size()方法獲取集合長度,會直接返回一個集合元素數量的變量值,而不會每次調用size()方法都重新計算下集合的元素數量再返回。下面我們在看下String.length()。

String.Length()

我們看下java.lang包下得String類,首先找到String類中的.length()方法:

/**
 * An immutable sequence of UTF-16 {@code char}s.
 * See {@link Character} for details about the relationship between {@code char} and
 * Unicode code points.
 *
 * @see StringBuffer
 * @see StringBuilder
 * @see Charset
 * @since 1.0
 */
public final class String implements Serializable, Comparable<String>, CharSequence {
	//省略部分代碼...
	
	 private final int count;

	//省略部分代碼...
	
    /**
     * Returns the number of {@code char}s in this string. If this string contains surrogate pairs,
     * this is not the same as the number of code points.
     */
    public int length() {
        return count;
    }
    
	//省略部分代碼...
}

我們發現跟ArrayList中的size()方法一樣,返回了一個int類型的成員變量count。這個count是怎麼賦值的我也不清楚,有興趣的可以去研究一下。

#總結
綜上所述,我們就可以知道List.size()和String.length()方法都是直接返回一個int類型變量值,而不會花費時間再去計算大小後返回,所以放心的去使用size()和length()方法吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章