[Java] コレクションの操作(ジェネリクス構文)

オブジェクトの集合を扱う。

以下の理由からアプリ内で集合を扱う場合には、配列ではなくまずコレクションを利用すべきとのこと。

> – 既知のデータ構造/アルゴリズムをそのまま取り込めるため、開発生産性に優れる。
> – 同様の理由からパフォーマンスにも優れる。
> – 共通的な操作をインターフェースとして定義しているので、データ構造/アルゴリズムによらず、同じように操作できる。

## 基本構文

通常は簡潔に書ける var 型推論を利用する。

“`java
var data = new ArrayList();
“`

変数型を強く意識する場合は、インターフェース型を利用する。

“`java
List data = new ArrayList<>();
“`

見慣れない `List<>` は Generics 構文で、汎用的なクラス・メソッドを特定の型に結びつけるための仕組み。
格納する値の型が正しいことをコンパイル時にチェックでき、値を取り出す場合のキャストも不要になる。 => (型安全)

## リスト

一般的には、以下で使い分ける。

– LinkedList … 連続して要素の挿入/削除が発生する、あるいはリストに順にアクセスする用途。
– ArrayList … それ以外の既存要素の取得や書き換えが主となる用途。

“`java
package com.example.arrayloop;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;

public class ArrayLoop {
private static String msg;

public static void main(String[] args) throws Exception {
StringBuilder msg = new StringBuilder();
// int[] array = {50, 60, 70, 80};
// var array = new ArrayList(Arrays.asList(50, 60, 70, 80));
var array = new LinkedList(Arrays.asList(50, 60, 70, 80));
for (int mps : array) {
var kmh = mps * 3600 / 1000;
msg.append(“最大瞬間風速”).append(mps).append(“m = 時速”).append(kmh).append(“km”).append(“\n”);
setMsg(msg.toString());
}

System.out.println(msg);
}

private static void setMsg(String msgString) {
msg = msgString;
}
}
“`

> – [イテレータ(拡張 for と型推論) | deadwood](https://www.d-wood.com/blog/2021/04/13_12252.html)

## セット

`HashSet` 数学における集合の概念に似ている。重複を許さない。
並び順は管理しない。

“`java
import java.util.HashSet;
:
var set = new HashSet(Arrays.asList(1, 20, 30, 1, 60, 20));
System.out.println(set); // [1, 20, 60, 30]
“`

`TreeSet` は、順番も持っている。

“`java
import java.util.TreeSet;
:
var set = new TreeSet(Arrays.asList(1, 20, 30, 1, 60, 20));
System.out.println(set); // [1, 20, 30, 60]
“`

## マップ

一意のキーと値のペアで管理されるデータ構造。
ディクショナリ、ハッシュ、連想配列に該当する。

唯一、Collection インターフェースを継承していないデータ構造。
そのまま拡張 for に渡すことが出来ない。

`HashMap` 最も基本的な実装。
キーの順序は保証されない。

“`java
import java.util.HashMap;
import java.util.Map;
:
var map = new HashMap(Map.of(“Rose”, “バラ”, “Sunflower”, “ひまわり”, “Morning Glory”, “あさがお”));
for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + “:” + entry.getValue());
}
// Rose:バラ
// Sunflower:ひまわり
// Morning Glory:あさがお
“`

`TreeMap` は順番に意味のある操作に利用する。

“`java
import java.util.TreeMap;
:
var map = new TreeMap(Map.of(“Rose”, “バラ”, “Sunflower”, “ひまわり”, “Morning Glory”, “あさがお”));
for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + “:” + entry.getValue());
}
// Morning Glory:あさがお
// Rose:バラ
// Sunflower:ひまわり
“`

key, value ペアが分かりづらい。

## スタック/キュー

`ArrayDeque` を利用する。

Stack (Last In First Out)

“`java
import java.util.ArrayDeque;
:
var data = new ArrayDeque();
data.addLast(10);
data.addLast(15);
data.addLast(30);

System.out.println(data); // [10, 15, 30]
System.out.println(data.removeLast()); // 30
System.out.println(data); // [10, 15]
“`

Queue (First In First Out)

“`java
import java.util.ArrayDeque;
:
var data = new ArrayDeque();
data.addLast(10);
data.addLast(15);
data.addLast(30);

System.out.println(data); // [10, 15, 30]
System.out.println(data.removeFirst()); // 10
System.out.println(data); // [15, 30]
“`