【Java】IteratorでList/Mapの要素を取得する

#目次
- 初めに
- Iterator(イテレータ)って何
- List系のIterator
- Map系のIterator
- ジェネリクス表現から拡張for文へ
- まとめ
- おわりに

##初めに
JavaでMap/Listを触ってると、

- **Listの要素すべてに対してなんかしたい！**
- **Mapの要素すべてに対して反復的に処理したい！**

っていう瞬間が少なからずあると思います。そんなときに便利なのが今回の**Iterator(イテレータ)**です。

実際のコードと一緒ににまとめたので参考にしてください。

※本文中のコード内におけるクラス名/変数名等は適宜読み替えてください。
※一部メインメソッド表記を省略している部分もあります。
※修正/改善点等あればおしえていただければと思います。

##Iterator(イテレータ)って何
####定義
>イテレータ（英語: iterator）とは、プログラミング言語において配列やそれに類似する集合的データ構造（コレクションあるいはコンテナ）の各要素に対する繰り返し処理の抽象化である。実際のプログラミング言語では、オブジェクトまたは文法などとして現れる。JISでは反復子（はんぷくし）と翻訳されている。 [wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%86%E3%83%AC%E3%83%BC%E3%82%BF)

上記の通り、**配列やそれに準ずるデータ**に対して、**繰り返し処理**を行うための**インターフェース**のことをIteratorと呼ぶ。

####Iteratorのメソッド
Iteratorクラスには以下2つのメソッドが宣言されている。

- next()
    -  繰り返し処理で次の要素を返す。
- hasNext()
    - 繰り返し処理でさらに要素がある場合に true を返す。
- remove()
    - 基になるコレクションから、反復子によって最後に返された要素を削除する。(任意のオペレーション)
    - ~~覚えなくていい~~覚えてもいい

上の2つが重要で、繰り返し処理では主にnext()とhasNext()を使う
他クラスでIteratorを使用する場合はメソッドを**オーバーライド**して使用する。
remove()の「任意のオペレーション」は、「Iteratorが呼ばれるオブジェクトにによってはサポートしていないものもある」の意味。

####記法
使用時は```Iterator<参照するオブジェクトの型>オブジェクト名```でインスタンス化する


以下で実際にそれぞれのクラスでの使用方法を確認する。


##List系のIterator
Listクラスには**Iteratableインターフェースが実装されている**ため、メソッドを呼び出すだけでIterator型のオブジェクトを取得できる。
[Listクラス詳細(オラクルHP)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html)
 
```IteratorDemo.java
public void IteratorDemo(){
// リスト作成
	List<String> list = new ArrayList<String>(); 
	list.add("イヌ");                           
	list.add("サル");                           
	list.add("キジ");                                                
// イテレータ取得、メソッド呼び出し
	Iterator<String> itList = list.iterator();
// 表示
	while (itList.hasNext()){                    
		String s = itList.next();
		System.out.println(s);
	}
}
```
```実行結果
実行結果:
イヌ
サル
キジ
```


##Map系のIterator
Mapクラスには**Iteratorインターフェースが実装されていない**ため、一度Iteratorインターフェースが実装されているクラス型のオブジェクトにしてからIteratorを取得する。


```IteratorDemo.java
// マップ作成 //                                                                             
	Map<Character, String> map = new HashMap<Character, String>();                      
	map.put('A', "あるふぁ");                                                               
	map.put('B', "ぶらぼー");                                                               
	map.put('C', "ちゃーりー");                                                              
                                                                                        
// イテレータ取得、メソッド呼び出し //                                                                                        
	// keySet()でSet型オブジェクトとしてキー一覧を取得          
	Iterator<Character> itMapKey = map.keySet().iterator();                             
                                                                                        
	// values()でCollection型オブジェクトとして値一覧を取得
	Iterator<String> itMapValue = map.values().iterator();                              
                                                                                        
	// entrySet()でSet<Map.Entry<K, V>型オブジェクトとしてキーと値の組み合わせを取得
	Iterator<Map.Entry<Character, String>> itEntry = map.entrySet().iterator();         
                                                                                        
                                                                                        
// 表示 //                                                                                
	while (itMapKey.hasNext()){                                                         
		char key = itMapKey.next();                                                     
		System.out.println(key);                                                        
	}                                                                                   
                                                                                
	while (itMapValue.hasNext()){                                                       
		String value = itMapValue.next();                                               
		System.out.println(value);                                                      
	}                                                                                   
                                                                               
	while(itEntry.hasNext()){                                                           
		Map.Entry<Character, String> entry = itEntry.next();                            
		System.out.println(entry);                                                      
	}                                                                                                                                    
```
```
実行結果:
A
B
C
あるふぁ
ぶらぼー
ちゃーりー
A=あるふぁ
B=ぶらぼー
C=ちゃーりー
```

##ジェネリクス表現から拡張for文へ
上記コード例ではジェネリクス**"＜＞"**を使った出力を行ったが、拡張for文を用いるこもできる。
List/Mapそれぞれのfor文での出力方法は以下。

```java
//表示結果は「Map系のイテレータ」部のコードと同じ

// Listの中身すべてを表示
for (String value : list){    
	System.out.println(value);
}                             
// Mapのキーをすべて表示
for (char key : map.keySet()){ 
	System.out.println(key);   
}
//マップの値をすべて表示
for (String value : map.values()){ 
	System.out.println(value);     
}
//マップのキーと値の組み合わせ(エントリ)をすべて表示
for (Map.Entry<Character, String> entry : map.entrySet()){
	System.out.println(entry);                            
}                                                                                                                   
```

##まとめ
- List系クラスはそのままIteratorを使用可能
- Map系クラスは、値をIteratorが実装されている型のオブジェクトへ変換してから使う。
- Map系のそれぞれの値取り出し時に使うメソッドは以下

|　ほしい要素　|　メソッド名　|　戻り値　|
|:---:|:---:|:---:|
|キーの一覧|map.keySet()|Set型|
|値の一覧|map.values()|Collection型|
|キーと値の組み合わせ一覧|map.entrySet()|Collection\<Entry\<K, V>>型|
##終わりに
ここまで読んでいただきありがとうございます。

まだまだ触れられてない部分もあるのでいつかまとめられたらな～とか思います。

「自作クラスにIterator実装する」みたいな記事もちらほら見かけたのでそっちもいつかはまとめてみたいですね。

では。