JAVA forとforeach

2937 ワード

結論:
forの方が効率的で、foreachの方が安全です.遍歴中にデータを変更する可能性がある場合はforeachを使用してスレッド内の一時変数だけ遍歴してforを使用します.
理由:
foreachはGetEnumeratorによってIEnumeratorオブジェクトを取得し、IEnumeratorオブジェクトによってMoveNext()メソッドを実行し、Currentプロパティを取得して遍歴します.以下の2つの書き方で、コンパイルしたコードは同じです.
//     :  
IList list = new ArrayList();  
IEnumerator iter = list.GetEnumerator();  
try  
{  
    while (iter.MoveNext())  
    {  
        Object obj = iter.Current;  
        //do something ...  
    }  
}  
finally  
{  
    IDisposable disposableObj = iter as IDisposable;  
    if (disposableObj != null)  
    {  
        disposableObj.Dispose();  
    }  
}  
  
//     :  
IList list = new ArrayList();  
foreach (Object obj in list)  
{  
    //do something ...  
}  

Javaソースの表示:
public class ArrayList  
{  
    //        ,ArrayList  ,        ,_version   1  
    private int _version;  
  
    public virtual int Add(object value)  
    {  
        int num1;  
        if (this._size == this._items.Length)  
        {  
            this.EnsureCapacity((this._size + 1));  
        }  
        this._items[this._size] = value;  
        ++this._version; //      
        this._size = ((num1 = this._size) + 1);  
        return num1;  
    }  
  
    public virtual void Clear()  
    {  
        Array.Clear(this._items, 0, this._size);  
        this._size = 0;  
        ++this._version; //      
    }  
  
    //    GetEnumerator  ,      FastArrayListEnumerator  
    //  ArrayListEnumeratorSimple  。  
    public virtual IEnumerator GetEnumerator()  
    {  
        if (base.GetType() == typeof(ArrayList))  
        {  
            return new ArrayList.FastArrayListEnumerator(this);  
        }  
        return new ArrayList.ArrayListEnumeratorSimple(this);  
    }  
}  

class FastArrayListEnumerator  
{  
    private int version;  
  
    internal FastArrayListEnumerator(ArrayList list)  
    {  
        this.list = list;  
        this.index = -1;  
  
        //    FastArrayListEnumerator   ArrayList      
        this.version = list._version;   
  
        this.lastIndex = (list._size - 1);  
    }  
  
    public bool MoveNext()  
    {  
        int num1;  
  
        //  ArrayList      ,  
        //     FastArrayListEnumerator           
        //     ,     。  
        if (this.version != this.list._version)  
        {  
            throw new InvalidOperationException(  
                Environment.GetResourceString("InvalidOperation_EnumFailedVersion")  
                );  
        }  
  
        //... ...   
    }  
} 

rrayListはパス_バージョンメンバー変数がバージョンIDとして使用される場合、Add、ClearなどのArrayListコンテンツの変更操作を実行するたびにバージョン番号が1ずつ加算され、GetEnumeratorメソッドを呼び出すたびにFastArrayListEnumeratorまたはArrayListEnumeratorSimpleオブジェクトが作成されます.FastArrayListEnumeratorオブジェクト構築時、その時点でArrayListのバージョン番号.MoveNext()操作を実行すると、ArrayListの現在のバージョン番号がFastArrayListEnumeratorオブジェクト構築時のバージョン番号と一致しているかどうかを確認し、一致しないと例外を放出します.