alphaのjava備忘録

alphaが勉強したことを書いていくブログ

拡張for文を使うには

Iteratorを調べたところで同じく繰返処理で使われる拡張for文についてもまとめてみる。拡張for文はArrayListやHashMapのようなコレクションに対して使用できるfor文。J2SE 5.0 (2004年)から搭載された新機能らしい。14年も前の話だから今では教科書にも載ってるわけね。



for文と比べたときのメリットは
 ・少ない記述で済む(変化式や終了条件を書かない)

Iteratorと比べたときのメリットは
 ・少ない記述で済む(Iterator変数を用意しなくていい)

逆にデメリットは
・終了条件にあたるものがないため、集合全部を必ず処理に使うことになる
Iterator変数にあたるものがないため、集合全部を必ず処理に使うことになる


基本的には拡張for文はIteratorより使われるらしい...昨日Iteratorを勉強した意味とは...


拡張for文の構文は
for(変数名 変数 : 集合){ 繰り返す処理 };

例えばArryaListの中身を拡張for文で出力したい場合、

import java.util.ArrayList;

class Main{
	public static void main(String[] args){
		ArrayList<String> al = new ArrayList<String>(){};
		al.add("aa");
		al.add("bb");
		al.add("cc");
		for(String s : al){
		System.out.println(s);
		}
	}
}

こういう風に使う。

実行結果
aa
bb
cc


じゃあHashMapで使う場合はどうするかというと、やっぱりHashMapそのまま繰返処理を行うのではないみたい。キーか値か必要な法をkeySer()(戻り値はSet型)かvalues()(戻り値はCollection型)をSet/Collection型変数に格納してから、その変数から中身を取得することになる。

import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.Collection;

class Main{
	public static void main(String[] args){
		HashMap<String,Double> hm = new HashMap<>();
		hm.put("key1",1.2);
		hm.put("key2",1.3);
		hm.put("key3",1.4);
		
		Set<String> keys = hm.keySet();
		for(String s  : keys){
			System.out.println(s);
		}
		Collection<Double> vals = hm.values();
		for(double d : vals){
		 	System.out.println(d);
		}
	}
}

(1)HashMapの中身を用意。put()でキーと値を格納。
(2)keySet()を実行し、戻り値としてキーの集合を取得。Set型変数 keysに戻り値を格納。
(3)拡張for文でSet型変数 keysから"key1","key2","key3"を順次1個ずつ取得。それぞれString 型なので拡張for文の変数はString s。
(4)sを出力。

(5)values()を実行し、戻り値として値の集合を取得。Collection型変数valsに戻り値を格納。
(6)拡張for文でCollection型変数valsから1.2,1.3,1.4 を順次1個ずつ取得。それぞれdouble型なので拡張for文の変数はdouble d。
(7)dを出力。

出力結果
key1
key2
key3
1.2
1.3
1.4


以下、余談。今回の記事を書く際に躓いた(コンパイルエラーが起きた)ポイントを自分用メモ。主にジェネリクスとコレクション関係。

ジェネリクスは参照型しか使用できない。プリミティブ型はダメ。
  Set <Integer> はOKだけど、Set はダメ。
  Set <Double> はOKだけど、Set はダメ。

・keySet()の戻り値を格納する変数はジェネリクスで同じ型を指定しなくてはいけない。
  Set<String> keys = hm.keySet(); はOK
  Set keys = hm.keySet();  はダメ

・values()の戻り値はCollection型であり、Setではない。
 親クラスのインスタンスは子クラスのインスタンスに入れることはできない、みたいな話?
  Collection <Double> vals = hm.values(); はOK
  Set <Double> vals = hm.values(); はOK

・プレビュー見て初めて気づいたけどはてな記法だとジェネリクスに使う不等号が消える消える!
 エスケープシーケンスで検索。