Iterable<T>
日本語 | 反復可能 |
英語 | iterable |
ふりがな | いてらぶる |
フリガナ | イテラブル |
J2SEに含まれるインタフェースのひとつ。パッケージも含めたインタフェース名はjava.lang.Iterable。
拡張forに渡せるようにするためのインタフェース。
このインタフェースの実装クラスは、拡張forに渡すことができるようになる。
Iterable<T>インタフェースはiterator()メソッドを持つため、このメソッドを実装する必要がある。
拡張forに渡すと、拡張forの内部でiterator()メソッドが呼び出される。
iterator()メソッドはイテレーターを返すよう実装しなければならない。この返したイテレーターを使用して、拡張forはループを行う。逆に言えば、「拡張forでループしたい配列やコレクション」のイテレーターを返せばよい、ということである。
Iterable<T>インタフェースはジェネリッククラスである。型引数には、iterator()メソッドで返すイテレーターであるIterator<E>の「E」と同じ型を指定すればよい。
ではそのIterator<E>の「E」には何を指定すればよいかというと、このイテレーターが拡張forに渡されてループされるのだから、すなわち拡張forで一周ごとに取得する要素の型、つまり「for( 型 変数 : コレクション )」の「型」を指定すればよい。
Iterable<T>インタフェースを実装することで、拡張forに渡すことができるようになり、より便利なクラスとなる。
ただし、その実装には注意すること。クラスが配列やコレクションを複数持つ場合でも、iterator()メソッドで返せるイテレーターはそのうちの1つだけである。
そのため、クラスを使う側が直感的に「どの配列やコレクションが拡張forでループされる」のか分かる場合でなければIterable<T>インタフェースを実装すべきではない。使用者にとって想定外の配列、コレクションが拡張forでループされた場合、バグの原因となりうるからである。
拡張forに渡せるようにするためのインタフェース。
このインタフェースの実装クラスは、拡張forに渡すことができるようになる。
Iterable<T>インタフェースはiterator()メソッドを持つため、このメソッドを実装する必要がある。
拡張forに渡すと、拡張forの内部でiterator()メソッドが呼び出される。
iterator()メソッドはイテレーターを返すよう実装しなければならない。この返したイテレーターを使用して、拡張forはループを行う。逆に言えば、「拡張forでループしたい配列やコレクション」のイテレーターを返せばよい、ということである。
Iterable<T>インタフェースはジェネリッククラスである。型引数には、iterator()メソッドで返すイテレーターであるIterator<E>の「E」と同じ型を指定すればよい。
ではそのIterator<E>の「E」には何を指定すればよいかというと、このイテレーターが拡張forに渡されてループされるのだから、すなわち拡張forで一周ごとに取得する要素の型、つまり「for( 型 変数 : コレクション )」の「型」を指定すればよい。
Iterable<T>インタフェースを実装することで、拡張forに渡すことができるようになり、より便利なクラスとなる。
ただし、その実装には注意すること。クラスが配列やコレクションを複数持つ場合でも、iterator()メソッドで返せるイテレーターはそのうちの1つだけである。
そのため、クラスを使う側が直感的に「どの配列やコレクションが拡張forでループされる」のか分かる場合でなければIterable<T>インタフェースを実装すべきではない。使用者にとって想定外の配列、コレクションが拡張forでループされた場合、バグの原因となりうるからである。
参考サイト
// Sample.java
import java.util.ArrayList;
import java.util.Iterator;
/**
* Iterable<T>インタフェースを実装するクラス。
*/
class HasArrayList implements Iterable<String>
{
/**
* ArrayList<E>をフィールドに持ちます。
*/
private ArrayList<String> arylst = new ArrayList<String>();
/**
* コンストラクタ。
*/
public HasArrayList()
{
arylst.add( "あいうえお" );
arylst.add( "かきくけこ" );
arylst.add( "さしすせそ" );
}
/**
* Iterable<T>インタフェースのiterator()メソッドを実装します。
* このメソッドを実装することで、このクラスは拡張forに
* 使用することができます。
*/
public Iterator<String> iterator()
{
// arylstのイテレーターを返します。
// 拡張forはこのイテレーターを使ってループします。
return arylst.iterator();
}
}
public class Sample
{
public static void main( String[] args )
{
// HasArrayListクラスのインスタンスを作ります。
HasArrayList hasArrayList = new HasArrayList();
// この中のarylstが、ArrayList<E>クラスのインスタンスを
// 参照しています。
// hasArrayListを拡張forに渡すと、Iterable<T>インタフェースの
// iterator()メソッドを実装したメソッドが呼び出されます。
for( String s : hasArrayList )
{
// arylst.iterator()で取得したイテレーターでループします。
// 一周ごとに、sにarylstの各要素が入るわけです。
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// このように、Iterable<T>インタフェースを実装することで、
// どんなクラスも拡張forに渡すことができます。
// 上記の拡張forは、以下の処理を内部的に行っています。
for( Iterator<String> ite = hasArrayList.iterator(); ite.hasNext(); )
{
String s = ite.next();
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// これを簡略化して書けるのが拡張forのメリットです。
// そして、その拡張forに直接渡せるのが、
// Iterable<T>インタフェースを実装するメリットです。
}
}
import java.util.ArrayList;
import java.util.Iterator;
/**
* Iterable<T>インタフェースを実装するクラス。
*/
class HasArrayList implements Iterable<String>
{
/**
* ArrayList<E>をフィールドに持ちます。
*/
private ArrayList<String> arylst = new ArrayList<String>();
/**
* コンストラクタ。
*/
public HasArrayList()
{
arylst.add( "あいうえお" );
arylst.add( "かきくけこ" );
arylst.add( "さしすせそ" );
}
/**
* Iterable<T>インタフェースのiterator()メソッドを実装します。
* このメソッドを実装することで、このクラスは拡張forに
* 使用することができます。
*/
public Iterator<String> iterator()
{
// arylstのイテレーターを返します。
// 拡張forはこのイテレーターを使ってループします。
return arylst.iterator();
}
}
public class Sample
{
public static void main( String[] args )
{
// HasArrayListクラスのインスタンスを作ります。
HasArrayList hasArrayList = new HasArrayList();
// この中のarylstが、ArrayList<E>クラスのインスタンスを
// 参照しています。
// hasArrayListを拡張forに渡すと、Iterable<T>インタフェースの
// iterator()メソッドを実装したメソッドが呼び出されます。
for( String s : hasArrayList )
{
// arylst.iterator()で取得したイテレーターでループします。
// 一周ごとに、sにarylstの各要素が入るわけです。
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// このように、Iterable<T>インタフェースを実装することで、
// どんなクラスも拡張forに渡すことができます。
// 上記の拡張forは、以下の処理を内部的に行っています。
for( Iterator<String> ite = hasArrayList.iterator(); ite.hasNext(); )
{
String s = ite.next();
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// これを簡略化して書けるのが拡張forのメリットです。
// そして、その拡張forに直接渡せるのが、
// Iterable<T>インタフェースを実装するメリットです。
}
}
// Sample.java import java.util.ArrayList; import java.util.Iterator; /** * Iterable<T>インタフェースを実装するクラス。 */ class HasArrayList implements Iterable<String> { /** * ArrayList<E>をフィールドに持ちます。 */ private ArrayList<String> arylst = new ArrayList<String>(); /** * コンストラクタ。 */ public HasArrayList() { arylst.add( "あいうえお" ); arylst.add( "かきくけこ" ); arylst.add( "さしすせそ" ); } /** * Iterable<T>インタフェースのiterator()メソッドを実装します。 * このメソッドを実装することで、このクラスは拡張forに * 使用することができます。 */ public Iterator<String> iterator() { // arylstのイテレーターを返します。 // 拡張forはこのイテレーターを使ってループします。 return arylst.iterator(); } } public class Sample { public static void main( String[] args ) { // HasArrayListクラスのインスタンスを作ります。 HasArrayList hasArrayList = new HasArrayList(); // この中のarylstが、ArrayList<E>クラスのインスタンスを // 参照しています。 // hasArrayListを拡張forに渡すと、Iterable<T>インタフェースの // iterator()メソッドを実装したメソッドが呼び出されます。 for( String s : hasArrayList ) { // arylst.iterator()で取得したイテレーターでループします。 // 一周ごとに、sにarylstの各要素が入るわけです。 System.out.print( s + ", " ); } System.out.println(); // あいうえお, かきくけこ, さしすせそ, // このように、Iterable<T>インタフェースを実装することで、 // どんなクラスも拡張forに渡すことができます。 // 上記の拡張forは、以下の処理を内部的に行っています。 for( Iterator<String> ite = hasArrayList.iterator(); ite.hasNext(); ) { String s = ite.next(); System.out.print( s + ", " ); } System.out.println(); // あいうえお, かきくけこ, さしすせそ, // これを簡略化して書けるのが拡張forのメリットです。 // そして、その拡張forに直接渡せるのが、 // Iterable<T>インタフェースを実装するメリットです。 } }