私はJava言語に少し慣れていないので、リスト(またはおそらく他のコレクション)を反復処理するすべての方法(または少なくとも非病理学的方法)と、それぞれの利点または欠点に慣れるようにしています。
List<E> list
オブジェクトがあれば、すべての要素をループする次の方法を知っています。
基本的なfor ループ(もちろん、同等のwhile
/ do while
ループもあります)
// Not recommended (see below)!
for (int i = 0; i < list.size(); i++) {
E element = list.get(i);
// 1 - can call methods of element
// 2 - can use 'i' to make index-based calls to methods of list
// ...
}
注:@amarseillanが指摘したようList
に、get
メソッドの実際の実装はを使用する場合ほど効率的でない可能性があるため、このフォームはs を反復する場合には適していませんIterator
。たとえば、LinkedList
実装はi番目の要素を取得するために、iに先行するすべての要素をトラバースする必要があります。
上記の例では、List
実装が「その場所を保存」して将来の反復をより効率的にする方法はありません。の場合、ArrayList
複雑さ/コストget
は一定の時間(O(1))であるため、実際には問題ではありませんが、aのLinkedList
場合、リストのサイズ(O(n))に比例します。
組み込みCollections
実装の計算の複雑さの詳細については、この質問を確認してください。
強化されたforループ(この質問でうまく説明されています)
for (E element : list) {
// 1 - can call methods of element
// ...
}
イテレータ
for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// ...
}
ListIterator
for (ListIterator<E> iter = list.listIterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// 3 - can use iter.add(...) to insert a new element into the list
// between element and iter->next()
// 4 - can use iter.set(...) to replace the current element
// ...
}
機能的なJava
list.stream().map(e -> e + 1); // Can apply a transformation function for e
Iterable.forEach、Stream.forEach、...
(Java 8のStream APIからのマップメソッド(@i_am_zeroの回答を参照))
実装するJava 8コレクションクラスIterable
(たとえば、すべてList
の)にforEach
メソッドが追加され、上記のforループステートメントの代わりに使用できるようになりました。(これは良い比較を提供する別の質問です。)
Arrays.asList(1,2,3,4).forEach(System.out::println);
// 1 - can call methods of an element
// 2 - would need reference to containing object to remove an item
// (TODO: someone please confirm / deny this)
// 3 - functionally separates iteration from the action
// being performed with each item.
Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
// Same capabilities as above plus potentially greater
// utilization of parallelism
// (caution: consequently, order of execution is not guaranteed,
// see [Stream.forEachOrdered][stream-foreach-ordered] for more
// information about this).
他にどのような方法がありますか?
(ちなみに、私の興味は、パフォーマンスを最適化したいという欲求にまったく由来するものではありません。開発者として私が利用できるフォームを知りたいだけです。)
List
具体的にはインターフェイスについての質問ですか?