こんにちは。サイオステクノロジーの川田です。
「Iterator」と「ListIterator」のメソッドを使ってみたので、メモとして残していきたいと思います。
Iterator
Iteratorとは?
Iterator(イテレータ)は日本語で「反復子」と翻訳されています。
繰り返し処理の抽象化となります。
要素を順番にアクセスする時に使用するインターフェースです。
抽象化とはどいうことか。
for文でぐるぐる回せばいいのではと思いました。
例えばfor文の場合は具体的に内容を提示する必要があります。
ループカウンタの初期値とか上限回数とか。。
データの要素数なんてわからない!そんなあやふやな場合でも
Iteratorを使えばループで要素を順番に取得することができるのです。
メソッド
メソッドは4つあります。
- hasNext()
次の要素がある場合はtrueを返します。
- next()
次の要素を返します。
- remove()
最後に返された要素を削除します。
- forEachRemaining()
各要素ごとに処理を実行します。Java8から追加になっています。
実装してみる
こちらの4つのメソッドを使ってみたいと思います。
「★」をつけている箇所が先ほどのメソッドになります。(3つ)
import java.util.Iterator; import java.util.List; import java.util.ArrayList; public class Test{ public static void main(String[] args) { List <Integer> list = new ArrayList <>(); list.add(1); list.add(0); list.add(5); list.add(6); Iterator<Integer> it = list.iterator(); while (it.hasNext()) { //★ int num = it.next(); //★ if (num == 0) { // 0は削除 it.remove(); //★ } } System.out.println(list); } }
numは「1」「0」「5」「6」と順番に処理されていきます。
不要な要素などをコレクションから削除する場合は17行目のように書きます。
こちらの実行結果はこのようになります。
[1, 5, 6]
※next()が呼び出されていない場合や既に remove() を呼び出している場合はエラーになります。
次にforEachRemaining()を実装してみます。
import java.util.Iterator; import java.util.List; import java.util.ArrayList; public class Test{ public static void main(String[] args) { List <Integer> list = new ArrayList <>(); list.add(1); list.add(0); list.add(5); list.add(6); Iterator<Integer> it = list.iterator(); it.forEachRemaining(e -> System.out.println(e)); //★ } }
Iteartorからの処理を書かなくていいので、ソースがスッキリしますね。
実行結果は以下の通りです。
1 0 5 6
ListIterator
ListIteratorとは?
Iteratorと同じでデータ集合を扱います。先ほどのIteratorとの違いは何なのかとなりますよね。
Iteratorは先頭から順番に処理を行っていましたが、ListIteratorは最後の要素から先頭にも処理が可能です。
逆方向もOKということです!
メソッド
メソッドがいくつかあるので見てみましょう。上3つはIteratorと同じです。
- hasNext()
Iteratorと一緒。次の要素がある場合はtrueを返します。
- next()
Iteratorと一緒。次の要素を返します。
- remove()
Iteratorと一緒。最後に返された要素を削除します。
- add()
指定された要素をnext()で返ってきた要素の前に追加します。
- set()
データの置き換えをします。
- hasPrevious()
逆方向。次の要素がある場合はtrueを返します。
- previous()
前の要素を返します。
- nextIndex()
次にnext()を呼び出したときに返ってくる要素のインデックス。
末尾はリストのサイズ。
- previousIndex()
次にprevious()を呼び出したときに返ってくる要素のインデックス。
先頭の場合は「-1」。
実装してみる
★が先ほどのメソッドになります。最初の方はIteratorと使い方が一緒です。
Iteratorから追加されたのが19行目のset()と20行目のadd()になります。
import java.util.ListIterator; import java.util.List; import java.util.ArrayList; public class Test2 { public static void main(String[] args) { List <Integer> list = new ArrayList <>(); list.add(1); list.add(0); list.add(5); list.add(6); ListIterator<Integer> it = list.listIterator(); while (it.hasNext()) { //★ int num = it.next(); //★ if (num == 0) { // 0は削除 it.remove(); //★ } else if (num == 6){ it.set(10); //★ it.add(11); //★ } } it.add(7); System.out.println(list); } }
メソッドの説明を基にlistの中身がどのように出力されるか想像してくださいね。
それでは実行結果を表示します!
[1, 5, 10, 11, 7]
removeで0が削除され、setで6→10に置換されています。
その次にaddで11が追加され、最後に7も追加されていることがわかりますね。
nextIndex()とhasPrevious()、previousIndex()も実装してみます。
不要な部分は削除しました。
import java.util.ListIterator; import java.util.List; import java.util.ArrayList; public class Test2 { public static void main(String[] args) { List <Integer> list = new ArrayList <>(); list.add(1); list.add(0); list.add(5); list.add(6); ListIterator<Integer> it = list.listIterator(); System.out.println("-----nextIndex"); while (it.hasNext()) { int num = it.next(); int num2 = it.nextIndex(); //★ System.out.println(num2); } System.out.println("-----previousIndex"); while (it.hasPrevious()) { //★ int num = it.previous(); //★ int num2 = it.previousIndex(); //★ System.out.println(num2); } } }
それでは早速実行してみます!
-----nextIndex 1 2 3 4 -----previousIndex 2 1 0 -1
予想は当たりましたか?
previousは逆方向になっていることがわかりますね!
まとめ
いかがでしたでしょうか?IteratorとListIteratorの違い分かりましたか?
今回はこの2つのメソッドを使ってまとめてみました。