menu
書いてる野郎
orebike@gmail.com
ArrayList
クラス等は拡張forに使えるので、じゃあ自分が独自に作ったクラスでそれをやりたい場合。
2段階。
まずこのようなコレクションっぽいクラスを用意する。
public class Hoge{ private String v1; private String v2; private String v3; private String v4; private String v5; public Hoge(String v1, String v2, String v3, String v4, String v5) { this.v1 = v1; this.v2 = v2; this.v3 = v3; this.v4 = v4; this.v5 = v5; } }
こいつを v1,v2…v5 と順番にやりたいなという話し。
当然だが、そもそも怒られて、↓のようには書けない。
Hoge hoge = new Hoge("a", "i", "u", "e", "o"); for(String s : hoge) { System.out.println(s); }
まずこいつが拡張forで使えるよという印をつけます。よくある -able 系のインターフェースです。
メソッドを実装しろと怒られるので実装もします。
public class Hoge implements Iterable<String>{ private String v1; private String v2; private String v3; private String v4; private String v5; public Hoge(String v1, String v2, String v3, String v4, String v5) { this.v1 = v1; this.v2 = v2; this.v3 = v3; this.v4 = v4; this.v5 = v5; } @Override public Iterator<String> iterator() { return null; } }
そうするととりあえず拡張forの構文で怒られなくなる。実行するとヌルポで落ちる。
ここで要素を順番に返すという Iterator という使い捨ての存在を作る。
特に拡張for以外では用途はほぼ無いので内部クラスとして作ってもよいだろう。
public class Hoge implements Iterable<String>{ private String v1; private String v2; private String v3; private String v4; private String v5; public Hoge(String v1, String v2, String v3, String v4, String v5) { this.v1 = v1; this.v2 = v2; this.v3 = v3; this.v4 = v4; this.v5 = v5; } @Override public Iterator<String> iterator() { HogeIterator it = new HogeIterator(); it.setHoge(this); return it; } public static class HogeIterator implements Iterator<String> { private String currentV; private Hoge hoge; public HogeIterator() { this.currentV = "v1"; } public void setHoge(Hoge hoge) { this.hoge = hoge; } @Override public boolean hasNext() { return !this.currentV.equals("finished"); } @Override public String next() { if(this.currentV.equals("v1")) { this.currentV = "v2"; return this.hoge.v1; } if(this.currentV.equals("v2")) { this.currentV = "v3"; return this.hoge.v2; } if(this.currentV.equals("v3")) { this.currentV = "v4"; return this.hoge.v3; } if(this.currentV.equals("v4")) { this.currentV = "v5"; return this.hoge.v4; } if(this.currentV.equals("v5")) { this.currentV = "finished"; return this.hoge.v5; } throw new IndexOutOfBoundsException(); } } }
このような感じの実装になる。実行すると a,i,u,e,o が出ることがわかると思う。
hasNext
は次があるのか否かを返す。これを見て拡張forは next
を呼び出すか否かの制御をする。
next
で実際の値を取り出す。名前は next だが意味としては取り出したい今の値を返す。