Javaの拡張for文のなかで簡単にindexを扱いたい
ものすごくシンプルな例としてList
普通にfor文で
for (int i = 0; i < strs.size(); i++) { System.out.println(i + ":" + strs.get(i)); }
ってやるのが普通なんですが、一般的に拡張for文の方が見やすいということで
int i = 0; for (String str : strs) { System.out.println(i + ":" + str); i++; }
みたいにやります。
ただ、どっちにしろ変数宣言とかインクリメントとか定型的な処理を書く必要があって、ちょっといけてない気がします。
なので、こんな風に書けないかと思って試してみました。(命名のセンスは置いておいて)
for (Elem<String> elem : ExtFor.loop(strs)) { System.out.println(elem.index() + ":" + elem.value()); }
これだと結構すっきりします。
他にはjQueryのeach()みたいな書き方も試してみました。
For.each(strs, new For.Function<String>() { public void execute(int index, String obj) { System.out.println(index + ":" + obj); } });
ちょっと長くなってしまいますね、今のJavaはこういうのはまだ苦手なんでしょう。
ExtForを使った3つ目の例は結構使えそうな気がしました。
最後に、
上の例で使ったクラス定義を以下に残します。
public class ExtFor { public static <T> Iterable<ExtFor.Elem<T>> loop(final Iterable<T> list) { return new Iterable<ExtFor.Elem<T>>() { @Override public Iterator<ExtFor.Elem<T>> iterator() { return ExtFor.iterator(list); } }; } private static <T> Iterator<ExtFor.Elem<T>> iterator(final Iterable<T> list) { return new Iterator<ExtFor.Elem<T>>() { private int counter = 0; private Iterator<T> iterator = list.iterator(); @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Elem<T> next() { Elem<T> elem = new Elem<T>(counter++, iterator.next()); return elem; } @Override public void remove() { throw new RuntimeException(); } }; } public static class Elem<T> { private final int index; private final T value; private Elem(int index, T value) { this.index = index; this.value = value; } public int index() { return this.index; } public T value() { return this.value; } } }
public class For { public static <T> void each(List<T> list, Function<T> function) { int length = list.size(); for (int index = 0; index < length; index++) { function.execute(index, list.get(index)); } } public static interface Function<T> { public void execute(int index, T obj); } }