拡張for
日本語 | ~のあいだ(拡張版) |
英語 | enhanced for、foreach、for in |
ふりがな | かくちょうふぉー |
フリガナ | カクチョウフォー |
forの書き方のひとつ。
J2SE 5.0で追加された構文。
配列もしくはコレクションの「最初の要素から最後の要素まで」を取得するためだけに特化した構文。
通常のforは「for( 初期化; 評価式; 更新 ){ 繰り返し行う処理 }」と書く。
対して拡張forは「for( 要素の型 要素を入れる変数 : 配列もしくはコレクション ){ 繰り返し行う処理 }」と書く。
このように書くことで、配列もしくはコレクションの全要素を取得するループを行う。
一周ごとに、「要素を入れる変数」へ要素の値が先頭から順番に格納される。
通常のforと違い、構文が非常にシンプルであるためプログラムを書きやすい。また「全要素の走査」に特化しているためプログラムが読みやすく可読性が高い。
反面、複雑なことはできない。各要素へ値を格納することはできない。ループが何周目かを取得することもできない。ループの範囲を変更する(たとえば「2番目から4番目まで」等)こともできない。逆順にループすることもできない。
このように汎用性は高くないが、そもそもforはほとんどこの拡張forのような使い方をするため、多くの場面で拡張forを使用することができるだろう。
拡張forの対象には配列もしくはコレクションを使用できる。
ただし、コレクションクラスであれば全てのクラスが使用できるわけではなく、iterator()メソッドを持つクラス、正確にはIterable<T>インタフェースを実装したクラスのみ使用できる。これは、拡張forが内部的にはイテレーターを使用しているからである。
そのため、HashMapクラスといった一部のクラスは拡張forに直接使用することはできない。Collection<E>インタフェースがIterable<T>インタフェースのサブクラスとなっているため、Collection<E>インタフェースを実装しているクラスは拡張forに使用することができる。これを目安に使用できるかどうか確認するといいだろう。
また、Iterable<T>インタフェースを実装すれば、APIのコレクションクラスでなくても拡張forに使用することができる。
他のプログラミング言語の「foreach」「for in」に似ていることからそう呼ばれることもある。
J2SE 5.0で追加された構文。
配列もしくはコレクションの「最初の要素から最後の要素まで」を取得するためだけに特化した構文。
通常のforは「for( 初期化; 評価式; 更新 ){ 繰り返し行う処理 }」と書く。
対して拡張forは「for( 要素の型 要素を入れる変数 : 配列もしくはコレクション ){ 繰り返し行う処理 }」と書く。
このように書くことで、配列もしくはコレクションの全要素を取得するループを行う。
一周ごとに、「要素を入れる変数」へ要素の値が先頭から順番に格納される。
通常のforと違い、構文が非常にシンプルであるためプログラムを書きやすい。また「全要素の走査」に特化しているためプログラムが読みやすく可読性が高い。
反面、複雑なことはできない。各要素へ値を格納することはできない。ループが何周目かを取得することもできない。ループの範囲を変更する(たとえば「2番目から4番目まで」等)こともできない。逆順にループすることもできない。
このように汎用性は高くないが、そもそもforはほとんどこの拡張forのような使い方をするため、多くの場面で拡張forを使用することができるだろう。
拡張forの対象には配列もしくはコレクションを使用できる。
ただし、コレクションクラスであれば全てのクラスが使用できるわけではなく、iterator()メソッドを持つクラス、正確にはIterable<T>インタフェースを実装したクラスのみ使用できる。これは、拡張forが内部的にはイテレーターを使用しているからである。
そのため、HashMapクラスといった一部のクラスは拡張forに直接使用することはできない。Collection<E>インタフェースがIterable<T>インタフェースのサブクラスとなっているため、Collection<E>インタフェースを実装しているクラスは拡張forに使用することができる。これを目安に使用できるかどうか確認するといいだろう。
また、Iterable<T>インタフェースを実装すれば、APIのコレクションクラスでなくても拡張forに使用することができる。
他のプログラミング言語の「foreach」「for in」に似ていることからそう呼ばれることもある。
参考サイト
- (参考サイトはありません)
// Sample.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class Sample
{
public static void main( String[] args )
{
// 配列の全要素を拡張forで出力します。
int[] ints = new int[] { 100, 200, 300 };
for( int i : ints )
{
// 一周ごとに、iに各要素が代入されます。
System.out.print( i + ", " );
// forループ内で「何周目か」を取得する方法は。
// ないため、必要ならカウンターを用意しましょう。
// また、要素の「取得」しかできないため、
// 各要素に値を格納することはできません。
}
System.out.println();
// 100, 200, 300,
// これは以下と同じです。
for( int iF1 = 0; iF1 < ints.length; iF1++ )
{
int i = ints[iF1];
System.out.print( i + ", " );
}
System.out.println();
// 100, 200, 300,
// また、ArrayListといったコレクションにも使用できます。
ArrayList<String> arylst = new ArrayList<String>();
arylst.add( "あいうえお" );
arylst.add( "かきくけこ" );
arylst.add( "さしすせそ" );
for( String s : arylst )
{
// 一周ごとに、sに各要素が代入されます。
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// これは以下と同じです。
for( Iterator<String> ite = arylst.iterator(); ite.hasNext(); )
{
String s = ite.next();
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// このように、コレクションの場合にはイテレーターを
// 使用するため、iterator()メソッドを持っていなければ
// (正確には、Iterable<T>インタフェースを実装
// していなければ)拡張for使えません。
// たとえば、HashMapクラスは直接使用できません。
HashMap<String,String> hashMap = new HashMap<String,String>();
hashMap.put( "キー0", "値0" );
hashMap.put( "キー1", "値1" );
hashMap.put( "キー2", "値2" );
// ※コンパイルエラーの例
// for( Object s : hashMap ){}
// ※javacのエラーメッセージ
// foreach は式のタイプに使用できません。
// ※Eclipseのエラーメッセージ
// java.lang.Iterable の配列またはインスタンスのみ
// 繰り返すことができます
// ※コンパイルエラーの例ここまで
// まぁこのように、キーと値両方受け取る方法が
// ないからそういう仕様になっているわけで、
// たとえばvalues()メソッドを使えば、値全部を拡張forで
// 出力することができます。
for( String s : hashMap.values() )
{
// 一周ごとに、sに各要素の「値」が代入されます。
System.out.print( s + ", " );
}
System.out.println();
// 値2, 値0, 値1,
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class Sample
{
public static void main( String[] args )
{
// 配列の全要素を拡張forで出力します。
int[] ints = new int[] { 100, 200, 300 };
for( int i : ints )
{
// 一周ごとに、iに各要素が代入されます。
System.out.print( i + ", " );
// forループ内で「何周目か」を取得する方法は。
// ないため、必要ならカウンターを用意しましょう。
// また、要素の「取得」しかできないため、
// 各要素に値を格納することはできません。
}
System.out.println();
// 100, 200, 300,
// これは以下と同じです。
for( int iF1 = 0; iF1 < ints.length; iF1++ )
{
int i = ints[iF1];
System.out.print( i + ", " );
}
System.out.println();
// 100, 200, 300,
// また、ArrayListといったコレクションにも使用できます。
ArrayList<String> arylst = new ArrayList<String>();
arylst.add( "あいうえお" );
arylst.add( "かきくけこ" );
arylst.add( "さしすせそ" );
for( String s : arylst )
{
// 一周ごとに、sに各要素が代入されます。
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// これは以下と同じです。
for( Iterator<String> ite = arylst.iterator(); ite.hasNext(); )
{
String s = ite.next();
System.out.print( s + ", " );
}
System.out.println();
// あいうえお, かきくけこ, さしすせそ,
// このように、コレクションの場合にはイテレーターを
// 使用するため、iterator()メソッドを持っていなければ
// (正確には、Iterable<T>インタフェースを実装
// していなければ)拡張for使えません。
// たとえば、HashMapクラスは直接使用できません。
HashMap<String,String> hashMap = new HashMap<String,String>();
hashMap.put( "キー0", "値0" );
hashMap.put( "キー1", "値1" );
hashMap.put( "キー2", "値2" );
// ※コンパイルエラーの例
// for( Object s : hashMap ){}
// ※javacのエラーメッセージ
// foreach は式のタイプに使用できません。
// ※Eclipseのエラーメッセージ
// java.lang.Iterable の配列またはインスタンスのみ
// 繰り返すことができます
// ※コンパイルエラーの例ここまで
// まぁこのように、キーと値両方受け取る方法が
// ないからそういう仕様になっているわけで、
// たとえばvalues()メソッドを使えば、値全部を拡張forで
// 出力することができます。
for( String s : hashMap.values() )
{
// 一周ごとに、sに各要素の「値」が代入されます。
System.out.print( s + ", " );
}
System.out.println();
// 値2, 値0, 値1,
}
}
// Sample.java import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; public class Sample { public static void main( String[] args ) { // 配列の全要素を拡張forで出力します。 int[] ints = new int[] { 100, 200, 300 }; for( int i : ints ) { // 一周ごとに、iに各要素が代入されます。 System.out.print( i + ", " ); // forループ内で「何周目か」を取得する方法は。 // ないため、必要ならカウンターを用意しましょう。 // また、要素の「取得」しかできないため、 // 各要素に値を格納することはできません。 } System.out.println(); // 100, 200, 300, // これは以下と同じです。 for( int iF1 = 0; iF1 < ints.length; iF1++ ) { int i = ints[iF1]; System.out.print( i + ", " ); } System.out.println(); // 100, 200, 300, // また、ArrayListといったコレクションにも使用できます。 ArrayList<String> arylst = new ArrayList<String>(); arylst.add( "あいうえお" ); arylst.add( "かきくけこ" ); arylst.add( "さしすせそ" ); for( String s : arylst ) { // 一周ごとに、sに各要素が代入されます。 System.out.print( s + ", " ); } System.out.println(); // あいうえお, かきくけこ, さしすせそ, // これは以下と同じです。 for( Iterator<String> ite = arylst.iterator(); ite.hasNext(); ) { String s = ite.next(); System.out.print( s + ", " ); } System.out.println(); // あいうえお, かきくけこ, さしすせそ, // このように、コレクションの場合にはイテレーターを // 使用するため、iterator()メソッドを持っていなければ // (正確には、Iterable<T>インタフェースを実装 // していなければ)拡張for使えません。 // たとえば、HashMapクラスは直接使用できません。 HashMap<String,String> hashMap = new HashMap<String,String>(); hashMap.put( "キー0", "値0" ); hashMap.put( "キー1", "値1" ); hashMap.put( "キー2", "値2" ); // ※コンパイルエラーの例 // for( Object s : hashMap ){} // ※javacのエラーメッセージ // foreach は式のタイプに使用できません。 // ※Eclipseのエラーメッセージ // java.lang.Iterable の配列またはインスタンスのみ // 繰り返すことができます // ※コンパイルエラーの例ここまで // まぁこのように、キーと値両方受け取る方法が // ないからそういう仕様になっているわけで、 // たとえばvalues()メソッドを使えば、値全部を拡張forで // 出力することができます。 for( String s : hashMap.values() ) { // 一周ごとに、sに各要素の「値」が代入されます。 System.out.print( s + ", " ); } System.out.println(); // 値2, 値0, 値1, } }