Javaの基礎知識(基礎編)

【Javaの基礎知識】配列・コレクション(List・Set・Map)の基本と活用法を解説!

Javaではデータを扱う方法として、配列(Array) と コレクション(List・Set・Map) の2つがあります。配列はシンプルで高速ですが、サイズ固定のため扱いにくい場面もあります。一方、コレクションは柔軟にデータを管理できるため、現在のJava開発では主流になっています。本記事では、配列の基本から List、Set、Map の使い方までを詳しく解説し、それぞれの違いと適切な選択方法についても説明します。

Java コレクション すぐ使えるコピペ例

JavaのList、Set、Mapの基本操作を今すぐ使える形でまとめました。ここだけ見ればコレクションの基本操作はすぐマスターできます。

操作ListSetMap
作成・初期化new ArrayList<>()new HashSet<>()new HashMap<>()
追加add("Java")add("Java")put("Java", 90)
取得get(0)なしget("Java")
削除remove("Java")remove("Java")remove("Java")
サイズ取得size()size()size()
クリアclear()clear()clear()
含む確認contains("Java")contains("Java")containsKey("Java")

 この表でコレクションの基本操作はすぐ使えますが、使い方の注意点や具体例を詳しく知りたい方は、以下の解説を参考にしてください。さらに実務で役立つコツやポイントもわかります。

Javaのコレクションフレームワークとは?

Javaのコレクションフレームワークは、データを効率的に管理・操作するための仕組みです。プログラムでは、多くのデータを扱う場面があり、それを適切に整理・検索・更新するためのデータ構造が必要になります。

従来、Javaでは配列(Array)が基本的なデータ構造として使われていましたが、配列はサイズが固定されているため、可変なデータを扱うには不便でした。そこで登場したのが、 ListSetMapといったコレクションです。

コレクションとは?

Javaの「コレクション」とは、データをまとめて管理するための仕組み です。例えば、複数のデータを扱うときに、配列( Array)を使う方法がありますが、配列はサイズを変更できないという制約があります。

一方で、コレクションを使うと、データを柔軟に追加・削除 できるため、より実用的です。また、リストのように「順番を保持」したり、重複を防ぐセットのような仕組みもあります。

コレクションにはいくつかの種類があり、用途に応じて使い分けます。

種類特徴例え(果物を保存する箱)
List順番を保持し、重複を許容ArrayList, LinkedList, Vector並べた順番を記憶できる箱
Set順番を保持せず、重複を許さないHashSet, TreeSet同じものを二度入れられない箱
Mapキーと値のペアでデータを管理HashMap, TreeMap名前とセットで保存できる箱

コレクションを利用することで、データを動的に追加・削除できるだけでなく、検索・ソート・重複管理などの高度な操作も可能になります。

List・Set・Mapは何につかう?

コレクションは「何に使うものか」を理解すると使い分けが簡単になります。

コレクションの用途

  • List → 可変長配列の代わり
     ➡️ 順序を管理しながらデータを扱うときに使います。
     配列より柔軟にデータの追加・削除が可能です。
     使用例: 商品一覧の管理、ToDoリスト、スケジュール管理など。


  • Map → 簡易データベースの代わり
     ➡️ キーと値でデータを管理・検索・更新したいときに使います。
     名前と電話番号、商品IDと在庫数のようなペア管理に最適です。
     使用例: ユーザーIDとユーザー名の管理、社員番号と給与情報の管理など。


  • Set → 重複排除・一意データ管理ツール
     ➡️ データクレンジング、重複排除、一意な値だけを管理したいときに使います。
     使用例: 名刺管理で同じ相手を重複登録しない、登録済みメールアドレスの重複チェックなど。

【補足】Setは“キャスト”して使うのが基本

Setは「重複しない一意なデータだけを管理するコレクション」です。そのため実務では“キャスト(濾過器)”のように使うことが前提になります。

例えば、リスト内の重複データを取り除きたいときは以下のように使用します。

List<String> list = Arrays.asList("A", "B", "A", "C");
Set<String> set = new HashSet<>(list); // 重複排除
System.out.println(set); // [A, B, C](順序は保証されない)

List<String> uniqueList = new ArrayList<>(set); // 再度リスト化して順次処理
System.out.println(uniqueList); // [A, B, C](順序は保証されない)

このように、重複排除後は再びListに戻して順序管理を行い処理するのが一般的です。

Setは「重複排除専用のツール」として使うことが基本であり、必要なときに取り出して使う用途には向いていない点を覚えておきましょう。

配列(Array)の基本とコレクションとの違い

Javaでは配列( Array)とコレクション( ListSetMap)の両方が存在します。ここでは、配列の特徴と、コレクションとの違いを解説します。

Javaにおける配列の現状

Javaでは、配列(Array)は古典的なデータ構造 であり、現在では ListSetMap などのコレクションを使うのが主流 になっています。

以下のような理由から、配列の使用は限定的になっています。

Javaでは配列(Array)は昔からある基本的なデータ構造ですが、今では List、Set、Map などのコレクションを使うのが一般的です。

配列が避けられる理由

  • 固定長で柔軟性に欠ける
    配列は int[] や String[] のように最初にサイズを決めると変更できません。
    可変長のデータには不便です。

  • ArrayListが配列の代わりになる
    ArrayListは内部で配列を使いながらも、要素の追加・削除が簡単にできます。
    可変長のデータ管理ではArrayListがよく使われます。

  • APIとの相性が良いのはコレクション
    Javaの標準APIの多くは List や Map を前提に設計されています。
    配列よりコレクションを使う方が開発しやすくなっています。

  • 配列が使われる場面もある
    配列はメモリ効率が良く処理速度も速いため、大量データ処理やアルゴリズム実装などパフォーマンスを重視する場面では使われ続けています。

配列の特徴

  • 固定長(サイズを変更できない)
  • 型の制約が厳しい(宣言時に型を決める必要がある)
  • 高速なインデックスアクセスが可能

配列の使い方

Javaで配列を使うと、同じ型のデータをまとめて管理できます。以下に配列の基本的な使い方とポイントをわかりやすく解説します。

配列の宣言と初期化

配列を使うには、最初に変数を宣言し、値を入れる必要があります。

int[] numbers = {1, 2, 3, 4, 5};
String[] names = new String[3];

要素の取得と変更

配列内の値はインデックス番号で取り出したり書き換えたりできます。

int firstNumber = numbers[0]; // 1
names[0] = "Alice";

配列の反復処理(for / foreach)

配列の中身を順番に処理したい場合は、for文や拡張for文(foreach)が便利です。

for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

for (int num : numbers) {
    System.out.println(num);
}

配列とコレクション(List)の違い

配列(Array)と List には次のような違いがあります。

特徴配列(Array)List
サイズ変更不可(固定長)可能(動的に追加・削除)
データ構造プリミティブ型とオブジェクト型オブジェクト型のみ
操作の柔軟性低レベルの操作(要素の直接操作)便利なメソッドが豊富( add()remove() など)

Arrays.asList() で配列を List に変換

配列を List に変換して使いたいときは Arrays.asList() を使うことができます。

List<String> list = Arrays.asList(names);
System.out.println(list.get(0)); // Alice

Listの基本と使い方

リスト( List)は、要素の順序を保持し、重複を許容するデータ構造です。配列とは異なり、可変長のデータを扱うことができ、要素の追加や削除が容易です。また、 ArrayListLinkedList のような異なる実装が存在し、それぞれ特徴があります。

本記事では、 List の基本的な特徴、主な実装クラス、操作方法について詳しく解説します。

Listの特徴

List は、Javaのコレクションフレームワークの中で最も基本的なデータ構造の一つであり、要素の順序を保持し、重複を許容する という特徴を持っています。配列と異なり、動的にサイズを変更できるため、データの追加・削除が柔軟に行えます。

ArrayListLinkedList などの異なる実装クラスがあり、それぞれの特性に応じて適切な選択が求められます。ここでは、 List の主な特徴について解説します。

Listの特徴

  • 順序を保持する(要素を追加した順番を維持)
  • 重複を許容する(同じ値を複数回格納可能)
  • インデックスでアクセス可能(get(index) で取得)

Listの主な実装クラス

Javaの Listインターフェースを実装する主なクラスである ArrayListLinkedListVector を比較した表です。

特徴ArrayList(普段使い)LinkedList(追加・削除向き)Vector(古い・同期処理向き)
中身の仕組み順番に並ぶ箱前後につながる箱順番に並ぶ箱(スレッド安全)
追加・削除後ろへの追加が得意間の追加・削除が得意遅め
データの取り出し速い(位置を指定して取れる)遅い(先頭から探す)速い
スレッド対応×(対応していない)×(対応していない)〇(対応している)
使う場面データが多く検索が多い時追加・削除が多い時古いコードで同期処理が必要な時

ArrayList

ArrayList は、内部的に可変長配列を使用しており、ランダムアクセスが高速です。要素の追加・取得が速い反面、途中の要素を削除するとシフト処理が発生し、パフォーマンスに影響を与えることがあります。

List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
System.out.println(list.get(0)); // Java

LinkedList

LinkedList は、要素がノードとしてリンクリストで管理されており、要素の追加・削除が高速です。一方で、ランダムアクセスの速度は ArrayList に比べて遅くなります。

List<String> linkedList = new LinkedList<>();
linkedList.add("C++");
linkedList.add("Ruby");
System.out.println(linkedList.get(1)); // Ruby

Vector(推奨されない)

VectorArrayList と似ていますが、スレッドセーフであるため、並行処理の環境で利用されることがあります。しかし、現在では ArrayList を使い、必要なら Collections.synchronizedList() を使用する方法が推奨されています。

List<String> vector = new Vector<>();
vector.add("Go");
vector.add("Swift");
System.out.println(vector.get(0)); // Go

Listの操作方法

List は、要素の追加・削除、取得、ループ処理などの操作が簡単に行えるデータ構造です。 ArrayListLinkedList を使用することで、データの管理や検索を効率的に行うことができます。

ここでは、 List における基本的な操作方法として、「要素の追加・削除」「要素の取得」「イテレーション(反復処理)」の使い方を紹介します。

Listの操作メソッド

Listの操作メソッドでは、要素の追加・削除、取得、検索、部分取得など基本的な使い方を覚えることが大切です。ここでは実務でよく使うメソッドを簡潔にまとめて解説します。

List<String> list = new ArrayList<>(Arrays.asList("Java", "Python", "C++"));

// set(): 指定した位置の要素を別の値に変更
list.set(1, "JavaScript"); // "Python" → "JavaScript"

// get(): 指定位置の要素を取得
String lang = list.get(0); // "Java"

// size(): 要素数を取得
int count = list.size(); // 3

// subList(): 一部を切り出し
List<String> sub = list.subList(0, 2); // ["Java", "JavaScript"]

// indexOf(): 指定要素のインデックスを取得
int index = list.indexOf("C++"); // 2

// remove(): 指定要素または位置の要素を削除
list.remove("JavaScript"); // 値で削除
list.remove(0); // インデックスで削除

// clear(): 全要素を削除
list.clear();

Setの基本と使い方

セット( Set)は、重複を許さないデータ構造です。リスト( List)とは異なり、同じ要素を複数回追加することができません。また、実装クラスによって、要素の順序やソートの有無が異なります。

本記事では、 Set の基本的な特徴、主な実装クラス、操作方法について詳しく解説します。

Setの特徴

Set は、重複を許さないデータ構造 であり、同じ要素を複数回追加することができません。そのため、ユニークなデータの管理 に適しています。

また、 Set の実装クラスによって、要素の順序やソートのルールが異なります。順序を保持しない HashSet、挿入順を維持する LinkedHashSet、自動ソートされる TreeSet など、用途に応じて適切な Set を選択することが重要です。

Setの特徴

  • 順序を保証しない(ただし、TreeSet は要素を自動的にソートする)
  • 重複を許さない(同じ要素が2回以上追加されることはない)
  • equals() と hashCode() の適切な実装が重要

Setの主な実装クラス

Javaの Setインターフェースを実装する代表的なクラスである HashSetLinkedHashSetTreeSet の特徴を比較します。

特徴HashSet(速さ重視)LinkedHashSet(順番+速さ)TreeSet(並び順重視)
仕組みハッシュ表ハッシュ表+順番管理自動ソート(木構造)
順番の扱い順番は気にしない入れた順を覚える小さい順に並ぶ
同じ値入らない(重複不可)入らない(重複不可)入らない(重複不可)
追加・削除の速さとても速い速い(順番管理分少し遅い)普通(並べ替えの分遅い)
検索の速さとても速いとても速い普通
使う場面速さ最優先で管理順番を保ちつつ管理常に並べた状態で管理

HashSet

HashSet は、ハッシュテーブルを使用して要素を格納するため、順序を保持しない 代わりに、高速な追加・削除・検索 を提供します。

Set<String> hashSet = new HashSet<>();
hashSet.add("Java");
hashSet.add("Python");
System.out.println(hashSet.contains("Java")); // true

LinkedHashSet

LinkedHashSet は、 HashSet の特性を持ちつつ、要素の挿入順を保持 します。そのため、データの順番を維持しながら、効率的に重複を防ぎたい場合に適しています。

Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("C++");
linkedHashSet.add("Ruby");
System.out.println(linkedHashSet); // [C++, Ruby]

TreeSet

TreeSet は、要素を自動的にソート するセットです。内部的には TreeMap を使用しており、追加・削除のコストは高めですが、常に昇順でデータを保持します。

Set<Integer> treeSet = new TreeSet<>();
treeSet.add(5);
treeSet.add(1);
treeSet.add(3);
System.out.println(treeSet); // [1, 3, 5](自動的にソートされる)

Setの操作方法

Set は、重複を許さず、要素の順序が保証されない(またはソートされる)データ構造です。基本的な操作として、「要素の追加・削除」「特定の要素が含まれているかのチェック」「セットの全要素を取得する反復処理(イテレーション)」が可能です。

List のようなインデックスアクセスはできませんが、その分、データの一意性を確保しながら効率的に管理 できる利点があります。ここでは、 Set の基本操作を詳しく解説します。

Setの操作メソッド

Setの操作メソッドでは、重複しないデータの管理や存在確認、要素数の取得、削除などの基本操作を覚えることが重要です。ここでは実務で使う基本的なSetの操作方法を簡潔に紹介します。

// Setの作成と初期化
Set<String> set = new HashSet<>(Arrays.asList("Java", "Python", "C++"));

// add(): 要素を追加
set.add("JavaScript");

// remove(): 要素を削除
set.remove("Python");

// contains(): 要素が含まれているか確認
boolean exists = set.contains("Java"); // true or false
System.out.println(exists);

// size(): 要素数を取得
int count = set.size(); // 3
System.out.println(count);

// isEmpty(): セットが空か確認
boolean empty = set.isEmpty(); // false
System.out.println(empty);

// clear(): 全要素を削除
set.clear();

// イテレーション(拡張for)
for (String item : set) {
  System.out.println(item);
}

// イテレーション(Iterator)
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
  System.out.println(iterator.next());
}

Mapの基本と使い方

マップ( Map)は、キーと値のペアでデータを管理 するデータ構造です。リスト( List)やセット( Set)とは異なり、特定のキーを使って値にアクセスできるため、効率的なデータ管理が可能です。

用途に応じて適切な Map を選択することが重要です。

本記事では、 Map の基本的な特徴、主な実装クラス、操作方法について解説します。

Mapの特徴

Map は、キーと値のペアでデータを管理するデータ構造 です。各キーは一意であり、同じキーに対して異なる値を設定すると、後から追加した値で上書きされます。

配列やリストとは異なり、 Map はデータをキーで管理できるため、特定の要素を高速に検索 するのに適しています。また、実装クラスによって、キーの順序やソートのルールが異なるため、用途に応じた適切な選択が重要です。

Mapの特徴

キーと値のペアを保持(キーを指定して値を取得できる)
キーの重複を許さない(同じキーは1つしか保持できない)
高速な検索が可能(適切な実装クラスを選べばパフォーマンスが向上)

Mapの主な実装クラス

Javaの Mapインターフェースを実装する代表的なクラスである HashMapLinkedHashMapTreeMap の特徴を比較します。

特徴HashMap(速さ重視)LinkedHashMap(順番+速さ)TreeMap(並び順重視)
仕組みハッシュ表ハッシュ表+順番管理自動ソート(木構造)
キーの順番順番なし入れた順を覚えるキーを小さい順に並べる
重複キーは×、値は〇キーは×、値は〇キーは×、値は〇
追加・削除の速さとても速い速い(順番管理で少し遅い)普通(並べ替えで遅め)
検索の速さとても速いとても速い普通
使う場面速さ最優先で管理順番を保ちながら管理キー順で整理して管理

HashMap

HashMap は、キーの順序を保持しない代わりに、高速な検索・追加・削除 を提供します。最も一般的に使用される Map の実装です。

Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Java", 1);
hashMap.put("Python", 2);
System.out.println(hashMap.get("Java")); // 1

LinkedHashMap

LinkedHashMap は、 HashMap の特性を持ちつつ、キーの挿入順を保持 します。データの順序を維持しながら、高速な検索を行いたい場合に適しています。

Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("C++", 3);
linkedHashMap.put("Ruby", 4);
System.out.println(linkedHashMap); // {C++=3, Ruby=4}

TreeMap

TreeMap は、キーを昇順にソート して保持する Map です。内部的に Red-Black Tree(赤黒木) を使用しており、検索や順序付きのデータ管理に適しています。

Map<Integer, String> treeMap = new TreeMap<>();
treeMap.put(5, "Five");
treeMap.put(1, "One");
treeMap.put(3, "Three");
System.out.println(treeMap); // {1=One, 3=Three, 5=Five}

Mapの操作方法

Map は、キーと値のペアでデータを管理し、特定のキーを使って高速にデータを取得できます。基本的な操作として、「要素の追加・取得・削除」「キーの検索」「全要素の反復処理」があります。

配列やリストと異なり、 Map ではインデックスによるアクセスはできませんが、その分、キーを使って効率的にデータを管理 できます。ここでは、 Map の基本的な操作方法を解説します。

Mapの操作メソッド

Mapの操作メソッドでは、キーと値の管理、データの取得・更新・削除、存在確認などが基本です。ここでは実務で役立つMapの使い方を簡潔にまとめて解説します。

// Mapの作成と初期化
Map<String, Integer> map = new HashMap<>();
map.put("Java", 90);
map.put("Python", 85);
map.put("C++", 80);

// put(): キーと値のペアを追加・更新
map.put("JavaScript", 88);

// get(): キーに対応する値を取得
int score = map.get("Java"); // 90
System.out.println(score);

// containsKey(): キーが存在するか確認
boolean hasKey = map.containsKey("Python"); // true
System.out.println(hasKey);

// containsValue(): 値が存在するか確認
boolean hasValue = map.containsValue(80); // true
System.out.println(hasValue);

// size(): 要素数を取得
int count = map.size(); // 4
System.out.println(count);

// isEmpty(): Mapが空か確認
boolean empty = map.isEmpty(); // false
System.out.println(empty);

// remove(): キーを指定して要素を削除
map.remove("C++");

// clear(): 全要素を削除
map.clear();

// キーセットでイテレーション
for (String key : map.keySet()) {
  System.out.println(key + " : " + map.get(key));
}

// Entryセットでイテレーション
for (Map.Entry<String, Integer> entry : map.entrySet()) {
  System.out.println(entry.getKey() + " : " + entry.getValue());
}

List・Set・Mapの違いを比較

ListSetMap は、それぞれ異なる特性を持つデータ構造です。適切なデータ構造を選択することで、プログラムのパフォーマンスや可読性を向上させることができます。

以下の表で、それぞれの特徴を比較し、用途に応じた選び方を解説します。

特徴ListSetMap
順序を保持×( TreeSetはソート順)×( LinkedHashMapは挿入順)
重複を許容×キーは×、値は〇
要素のアクセス方法インデックスイテレーションキーを指定

適切なデータ構造の選び方

用途に応じて、以下のように ListSetMap を使い分けると効果的です。

  • 順序を保持し、重複を許容するデータを扱いたい場合List
  • 重複を許さず、順序を気にしないデータを管理したい場合Set
  • キーと値のペアでデータを管理し、高速な検索をしたい場合Map

例えば、以下のようなケースで適切なデータ構造を選ぶことができます。

  • 同じ値を複数回扱い、要素の順序を保持したい → ArrayListList
  • 重複のないユニークな値の集合を管理したい → HashSetSet
  • 特定のキーを使って素早く値を検索したい → HashMapMap

データの管理方法に応じて、適切なデータ構造を選択することが重要です。 List は順序付きのデータ、 Set はユニークな要素、 Map はキーと値のペアを管理するのに適しています。

よくある質問(FAQ)

Q: ArrayListとLinkedListはどちらを使うべき?

A: 読み取りが多いなら ArrayList、挿入・削除が多いなら LinkedList を選ぶのが適切です。

  • ArrayList は、ランダムアクセスが高速であり、データの検索や取得を頻繁に行う場合に適しています。
  • LinkedList は、要素の追加・削除が頻繁に発生する場合に有利ですが、ランダムアクセスは遅くなります。

Q: HashSetに要素を追加すると順序が変わるのはなぜ?

A: HashSet は、ハッシュ値を基に要素を格納 するため、順序が保証されません。

内部的にハッシュテーブルを使用しているため、要素の順番はデータのハッシュ値によって決まり、挿入した順番通りにはなりません。

もし順序を維持したい場合は、代わりに LinkedHashSet を使用すると、挿入順が保持されます。

Q: HashMapのキーはどのように管理される?

A: HashMap は、 hashCode() を利用してキーの位置を決定し、同じハッシュ値の場合は equals() で比較して管理します。

  • キーの hashCode() メソッドを利用し、ハッシュテーブルのどこに格納するかを決定します。
  • 同じハッシュ値のキーが複数存在する可能性があるため、ハッシュの衝突(コリジョン) を防ぐために equals() でキーの内容を比較します。
  • 衝突が発生した場合、内部的にリストやツリー構造を使って管理し、パフォーマンスを維持します。

まとめ

Javaの ListSetMap は、それぞれ異なる特性を持つデータ構造です。用途に応じて適切なデータ構造を選択することで、プログラムのパフォーマンスを向上させることができます。

データ構造ごとの特徴

Javaの ListSetMap は、それぞれ異なる特性を持つデータ構造です。適切なデータ構造を選択することで、プログラムの可読性やパフォーマンスを向上させることができます。

以下の表では、それぞれのデータ構造の主な用途と特徴を整理し、どのような場面で使うべきかを分かりやすく比較しています。

データ構造主な用途特徴
List順序を保持し、重複を許容したデータ管理インデックスでアクセス可能 / ランダムアクセスが速い
Set重複を防ぎながらデータを管理順序なし(TreeSetはソート)/ 高速な検索が可能
Mapキーと値のペアでデータを管理キーを使った高速なデータ検索が可能

適切なデータ構造の選び方

  • 順序を保持し、重複を許容したい場合List(例: ArrayList
  • 重複を許さず、一意のデータを管理したい場合Set(例: HashSet
  • キーと値のペアでデータを管理したい場合Map(例: HashMap

今後の活用

適切なデータ構造を選択することは、効率的なプログラム設計の第一歩です。各データ構造の特性をしっかり理解し、状況に応じた適切な使い分けを実践しましょう。

この記事を読んだら、次は 「【Javaの基礎知識】スレッドと並行処理の基本を徹底解説!」 を読むのがおすすめです!

よく読まれている記事

1

IT入門シリーズ 🟢 STEP 1: ITの基礎を知る(ITとは何か?) 📌 IT初心者が最初に学ぶべき基本知識。ITの概念、ネットワーク、OS、クラウドの仕組みを学ぶ ...

2

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか? 無料で使えるだけでなく、高い柔軟 ...

3

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-Javaの基礎知識(基礎編)