【Java】デザインパターンをやってみた 〜 Iterator/ListIterator編 ~

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【4/18開催】VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

こんにちは。サイオステクノロジーの川田です。

「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つのメソッドを使ってまとめてみました。

アバター画像
About kawada 25 Articles
Webアプリケーション開発を行っており、プログラミング初心者向けの記事や動画編集に関する内容を中心とした記事を執筆しています。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる