[Java] コレクションの操作(ジェネリクス構文)
オブジェクトの集合を扱う。
以下の理由からアプリ内で集合を扱う場合には、配列ではなくまずコレクションを利用すべきとのこと。
- 既知のデータ構造/アルゴリズムをそのまま取り込めるため、開発生産性に優れる。
- 同様の理由からパフォーマンスにも優れる。
- 共通的な操作をインターフェースとして定義しているので、データ構造/アルゴリズムによらず、同じように操作できる。
Contents
基本構文
通常は簡潔に書ける var 型推論を利用する。
var data = new ArrayList();
変数型を強く意識する場合は、インターフェース型を利用する。
List<String> data = new ArrayList<>();
見慣れない List<>
は Generics 構文で、汎用的なクラス・メソッドを特定の型に結びつけるための仕組み。
格納する値の型が正しいことをコンパイル時にチェックでき、値を取り出す場合のキャストも不要になる。 => (型安全)
リスト
一般的には、以下で使い分ける。
- LinkedList … 連続して要素の挿入/削除が発生する、あるいはリストに順にアクセスする用途。
- ArrayList … それ以外の既存要素の取得や書き換えが主となる用途。
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<Integer>(Arrays.asList(50, 60, 70, 80));
var array = new LinkedList<Integer>(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;
}
}
セット
HashSet
数学における集合の概念に似ている。重複を許さない。
並び順は管理しない。
import java.util.HashSet;
:
var set = new HashSet<Integer>(Arrays.asList(1, 20, 30, 1, 60, 20));
System.out.println(set); // [1, 20, 60, 30]
TreeSet
は、順番も持っている。
import java.util.TreeSet;
:
var set = new TreeSet<Integer>(Arrays.asList(1, 20, 30, 1, 60, 20));
System.out.println(set); // [1, 20, 30, 60]
マップ
一意のキーと値のペアで管理されるデータ構造。
ディクショナリ、ハッシュ、連想配列に該当する。
唯一、Collection インターフェースを継承していないデータ構造。
そのまま拡張 for に渡すことが出来ない。
HashMap
最も基本的な実装。
キーの順序は保証されない。
import java.util.HashMap;
import java.util.Map;
:
var map = new HashMap<String, String>(Map.of("Rose", "バラ", "Sunflower", "ひまわり", "Morning Glory", "あさがお"));
for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// Rose:バラ
// Sunflower:ひまわり
// Morning Glory:あさがお
TreeMap
は順番に意味のある操作に利用する。
import java.util.TreeMap;
:
var map = new TreeMap<String, String>(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)
import java.util.ArrayDeque;
:
var data = new ArrayDeque<Integer>();
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)
import java.util.ArrayDeque;
:
var data = new ArrayDeque<Integer>();
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]