【Java】コレクションについて

## コレクションとは
多くの要素を1つにまとめたオブジェクトを指す。複数のオブジェクトをまとめて取り扱うための考え方としてコレクションフレームワークが提供され、用途に応じたクラスやインタフェースが提供される。

## Listインタフェース
要素の重複を許可、順序づけを行いたい場合に使う。ArrayListクラスが代表的。

```ruby:Java(Main.java)
import java.util.ArrayList;

public class Main {
	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<>();
		Integer i1 = 11;
		int i2 = 20;
		Integer i3 = 33;
		list.add(i1);
		list.add(i2);
		list.add(i3);
		
		for(int i = 0;i < list.size();i++) {
			System.out.println(list.get(i));
		}
	}	
}
```

結果
```
11
20
33
```

見た目は配列(int[])にそっくりだが、配列とListインタフェースは何が違うのか。

|  |Listインタフェース  |配列  |
|---|---|---|
|データ保持  |新しい要素が追加されるたびにメモリ確保  |はじめにメモリ上の連続した領域を確保  |
|要素  |自由に要素数増減・挿入・入れ替え可能  |要素数増減はできず、要素の入れ替えは元の要素を削除しないといけない  |

またListインタフェースで使える代表的なメソッドは以下。
①size()
リストの要素数を取得
②get(index)
indexを指定してリストの要素を取得
③add(youso)
要素をリストに追加
④remove(index)
indexを指定して要素削除

さらにはIntegerとintの両方を使って値を追加している。ArrayListはIntegerオブジェクトを格納できるlistとして宣言されている。int(基本データ型)を格納しようとしているが、BoxingによりInteger型に自動変換されて代入される。

:::note info
オートボクシングとアンボクシング
オートボクシングはコンストラクタやメソッドなどを使わずに、基本データ型をラッパークラスに格納すること。アンボクシングは逆にラッパークラスに格納した値を基本データ型として扱うこと
:::

## setインタフェース
要素の重複を許さない、順不同でデータを扱う場合に使う。
```ruby:Java(Main.java)
import java.util.HashSet;

public class Main {
	public static void main(String[] args) {
		String[] ary = {"AAA","BBB","CCC"};
		HashSet<String> hashset = new HashSet<>();
		hashset.add(ary[2]);
		hashset.add(ary[1]);
		hashset.add(ary[0]);
		hashset.add(ary[2]);
		
		System.out.println(hashset.size());
		
		for(String s: hashset) {
			System.out.println(s);
		}
		System.out.println();
		hashset.remove("AAA");
		
		for(String s: hashset) {
			System.out.println(s);
		}
		
		hashset.clear();
		System.out.println();
		
		System.out.println("hashsetは");
		for(String s: hashset) {
			System.out.println(s);
		}
			
	}	
}
```


結果
```
3
AAA
CCC
BBB

CCC
BBB

hashsetは
```
Setインタフェースで使える代表的なメソッドは以下の通り。
①size()
セットの要素数を取得
②add(youso)
要素をリストに追加
③remove(index)
indexを指定して要素を削除
④clear()
要素の全削除。ここでは**要素はnullになるのではなく空になる**。なのでsize()で出力すると0になるし、for文で回しても何も表示されなくなる。

## Mapインタフェース
データをキーと値のペアで管理する場合に使う。キーは一意だが、値は重複可能。
```ruby:Java(Main.java)
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		HashMap<Integer,String> map = new HashMap<>();
		map.put(0,"AAA");
		map.put(2,"BBB");
		map.put(4,"CCC");
		map.put(0,"DDD");
		
		for(int i = 0;i < map.size();i++) {
			System.out.println(map.get(i));
		}
		System.out.println();
		
		Set<Integer> keys = map.keySet();
		for(Integer key : keys) {
			System.out.println(key);
		}
		
		System.out.println();
		
		Collection<String> values = map.values();
		for(String s : values) {
			System.out.println(s);
		}
	}	
}
```
結果
```
DDD
null
BBB

0
2
4

DDD
BBB
CCC
```

Mapインタフェースで使える代表的なメソッドは以下の通り。
①size()
マップの要素数取得。
①put(key,value)
キーと値をマップに追加。
③remove(key)
キーを指定することで、要素削除。キーに対応する部分はnullになる。
④clear()
要素の全削除。ここでは**要素はnullになるのではなく空になる**。なのでsize()で出力すると0になるし、for文で回しても何も表示されなくなる。
⑤keySet()
キーをセットで取得。
⑥values()
値をコレクションで取得。

## 任意の型で宣言するときの記載の仕方(Java Silver用)
以下は何を表しているだろうか？

```
<T> Collection<T> foo(Collection<T> c){
			return null;
		}
```

Tとは何か？これは任意の型を表している。これをオーバーロード・オーバーライドすると以下の書き方になる。

オーバーロード
```
<T> Collection<T> foo(List<T> c){
			return null;
		}
		
		<T> Collection<T> foo(Map c){
			return null;
		}
```

オーバーライド
```
<T> Collection<T> foo(Collection<T> c){
			//例としてコレクションの内容を複製して返す処理を実装
			Collection<T> result = new ArrayList<>(c);
			return null;
		}
```

では以下のソースはどうだろうか。
```
<T> Collection<T> foo(Collection<String> c){
			return null;
		}
```

ここでは引数のCollectionの型パラメータが異なっている。オーバーライド時にサブクラスで型パラメータを変えるとコンパイルエラーとなるため注意。またシグネチャは型パラメータに含まれないためオーバーロードと捉えられることは無い。

## まとめ
* コレクションとは多くの要素を1つにまとめたオブジェクト
* Listインタフェースは要素の重複を許可、順序づけを行いたい場合に使う
* setインタフェースは要素の重複を許さない、順不同でデータを扱う場合に使う
* Mapインタフェースはデータをキーと値のペアで管理する場合に使う
* 引数の型パラメータのみを変えてメソッドを再定義するとコンパイルエラーになる