JAVA forとforeach
2937 ワード
結論:
forの方が効率的で、foreachの方が安全です.遍歴中にデータを変更する可能性がある場合はforeachを使用してスレッド内の一時変数だけ遍歴してforを使用します.
理由:
foreachはGetEnumeratorによってIEnumeratorオブジェクトを取得し、IEnumeratorオブジェクトによってMoveNext()メソッドを実行し、Currentプロパティを取得して遍歴します.以下の2つの書き方で、コンパイルしたコードは同じです.
Javaソースの表示:
rrayListはパス_バージョンメンバー変数がバージョンIDとして使用される場合、Add、ClearなどのArrayListコンテンツの変更操作を実行するたびにバージョン番号が1ずつ加算され、GetEnumeratorメソッドを呼び出すたびにFastArrayListEnumeratorまたはArrayListEnumeratorSimpleオブジェクトが作成されます.FastArrayListEnumeratorオブジェクト構築時、その時点でArrayListのバージョン番号.MoveNext()操作を実行すると、ArrayListの現在のバージョン番号がFastArrayListEnumeratorオブジェクト構築時のバージョン番号と一致しているかどうかを確認し、一致しないと例外を放出します.
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オブジェクト構築時のバージョン番号と一致しているかどうかを確認し、一致しないと例外を放出します.