DATE : 2006/04/03 (Mon)
「ArrayList と LinkedList の使い分け」では、ランダムアクセスという言葉が出てきました。
リストの要素にアクセスする際には、ランダムアクセスとシーケンシャルアクセス(順次アクセス)の2通りがあります。
ランダムアクセスとは、適当な位置の要素に直接アクセスすることを言い、シーケンシャルアクセスとは、先頭の要素から順番にアクセスすることを言います。(参考文献:ランダムアクセス・順次アクセス(IT 用語辞典 e-Words))
ここでは、リストへランダムアクセスする方法とシーケンシャルアクセスする方法をメモしておきます。
簡単な見分け方
簡単に言うと、java.util.List#get(int) などで要素番号を指定して要素にアクセスするとランダムアクセス、java.util.List#iterate() などから java.util.Iterator を取得して要素にアクセスするとシーケンシャルアクセスになります。
コード例
以下のコードは、List へシーケンシャルアクセスを行った(つもり)の例です。
List list = new ArrayList();
// get メソッドでアクセス
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
// obj を処理
}
// Iterator でアクセス
for (Iterator i = list.iterator(); i.hasNext(); ) {
Object obj = i.next();
// obj を処理
}
しかし、 get メソッドでアクセスする方法は、実はランダムアクセスとなります。
人間から見れば get メソッドでアクセスする方法も Iterator でアクセスする方法も、シーケンシャルアクセスしているように見えます。
しかし、処理されている List 側から見れば、get メソッドでアクセスする方法はランダムアクセスなのです。
と言うのも、get メソッドでアクセスする場合、List の内部は次にアクセスされるであろう要素を知りません。ただ単に i という要素番号が外部から渡されてくるだけです。
それに対し Iterator は、次にアクセスされる要素の番号を内部に持っています。
なので、要素番号を使ってアクセスするとランダムアクセス、Iterator を使ってアクセスするとシーケンシャルアクセスになるというわけです。
LinkedList はランダムアクセスに弱いので、Iterator を使ってアクセスした方が良いと言えそうです。
For-Each ループ
ところで、Iterator を使った処理はちょっと見づらくありませんか?
List list = new ArrayList();
for (Iterator i = list.iterator(); i.hasNext(); ) {
Object obj = i.next();
// obj を処理
}
そこで Java SE 5 からは、「For-Each ループ」が導入されました。
上のコードは、以下のように書き直せます。
List list = new ArrayList();
for (Object obj : list) {
// obj を処理
}