2018年06月10日

Java Iterableインターフェース/Iteratorインターフェースの実装例

JavaでのIterableインターフェース/Iteratorインターフェースの実装例です。

サンプルのコード、クラスPrimeNumbersは整数を与えておくと、Iteratorを介して与えた整数以下のすべての素数を返します。

Iteratorインターフェースがイテレータを実装するためのもので、
Iterableインターフェースは拡張For文へ渡すためのもの、という役割です。

PrimeNumbersクラス
import java.util.Iterator;

/**
* 素数を計算するクラス
*/
public class PrimeNumbers implements Iterable<Integer>, Iterator<Integer> {

/** 与えられた整数 */
private int myNumber;
/** 現在の算出素数 */
private int curPrimeNumber;

/**
* コンストラクタ
* @param myNumber 与えられた整数
*/
public PrimeNumbers(int myNumber) {
super();
this.myNumber = myNumber;
curPrimeNumber = 1;
}

/**
* 要素のイテレータを返す。
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<Integer> iterator() {
// 自身のインスタンスを返す
return this;
}

/**
* 反復処理でさらに要素がある場合にtrueを返す。
* @see java.util.Iterator#hasNext()
*/
@Override
public boolean hasNext() {
// 与えられた整数が1以下なら終了
if (myNumber <= 1)
return false;

// 現在の算出素数が与えられた整数に達していれば終了
if (myNumber == curPrimeNumber)
return false;

int counter;
// 前回素数の次の値から開始
counter = curPrimeNumber + 1;

// 開始値から順に素数であるかをチェックする
for (int i = counter; i <= myNumber; i++) {
int j;
for (j = 2; j <= counter; j++) {
// 2から順番に割っていって、割り切れれば抜ける
if ((counter % j) == 0) {
break;
}
}
// 割り切れる値がチェック対象の整数しかなければ素数
if (j == counter) {
curPrimeNumber = counter;
return true;
}
counter++;
}
return false;
}

/**
* 反復処理で次の要素を返す。
* @see java.util.Iterator#next()
*/
@Override
public Integer next() {
// 現在の算出素数を返す
return curPrimeNumber;
}
}
呼び出し方
public class MyClass {
    public static void main(String... args) {

        // 整数を指定
        final int myNumber = 200;
        // 素数クラスを生成
        PrimeNumbers pNum = new PrimeNumbers(myNumber);

        // 指定整数以下の素数をすべて列挙
        for (Integer cur : pNum) {
            System.out.println(cur);
        }
    }
}

なお、拡張For文を使うには当該のクラスにIterable#iterator()の実装があればよく、
Iterator<E>の実装(implements)は必須ではない。
なので以下のような書き方も可能(動作は全く同じ)。
import java.util.Iterator;

/**
* 素数を計算するクラス
*/
public class PrimeNumbers implements Iterable<Integer> {

/** 与えられた整数 */
private int myNumber;
/** 現在の算出素数 */
private int curPrimeNumber;

/**
* コンストラクタ
* @param myNumber 与えられた整数
*/
public PrimeNumbers(int myNumber) {
super();
this.myNumber = myNumber;
curPrimeNumber = 1;
}

/**
* 要素のイテレータを返す。
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<Integer> iterator() {

// Iteratorインターフェースの実装
Iterator<Integer> iterator = new Iterator<Integer>() {
/**
* 反復処理でさらに要素がある場合にtrueを返す。
* @see java.util.Iterator#hasNext()
*/
@Override
public boolean hasNext() {
// 与えられた整数が1以下なら終了
if (myNumber <= 1)
return false;

// 現在の算出素数が与えられた整数に達していれば終了
if (myNumber == curPrimeNumber)
return false;

int counter;
// 前回素数の次の値から開始
counter = curPrimeNumber + 1;

// 開始値から順に素数であるかをチェックする
for (int i = counter; i <= myNumber; i++) {
int j;
for (j = 2; j <= counter; j++) {
// 2から順番に割っていって、割り切れれば抜ける
if ((counter % j) == 0) {
break;
}
}
// 割り切れる値がチェック対象の整数しかなければ素数
if (j == counter) {
curPrimeNumber = counter;
return true;
}
counter++;
}
return false;
}

/**
* 反復処理で次の要素を返す。
* @see java.util.Iterator#next()
*/
@Override
public Integer next() {
// 現在の算出素数を返す
return curPrimeNumber;
}
};

// イテレータを返す
return iterator;
}
}
タグ:JAVA
posted by Hiro at 12:06| Comment(0) | プログラム