💻

配列(Array)を深掘りする ― 「箱」の向こう側を理解する

に公開

1. はじめに

配列はプログラミングの基本ですが、ただの「同じ型の値を並べる箱」だと思っていませんか?
実は、その設計にはコンピュータの内部構造や効率性が深く関わっています。この記事では、配列の「なぜそう作られているのか」を掘り下げていきます。

2. 配列の本質 ― なぜ固定長なのか?

配列とは、同じ型のデータを連続したメモリ領域に格納し、インデックスでアクセスする仕組みです。

int[] scores = {70, 85, 90};
System.out.println(scores[0]); // → 70

ポイントは 「固定長」「同型」 という性質です。
これは単なるルールではなく、CPUやコンパイラの効率を最大化するために生まれた設計です。

  • 固定長の理由:連続したメモリ領域を確保すると、CPUがまとめて読み込むことができ、高速化されます。
    → イメージ:1つずつ箱を開けるよりも、まとめて一気に箱を取る方が早い。

  • 同型の理由:型サイズが一定なら、インデックスから正確なメモリアドレスを計算できる。
    例:int型(4バイト)なら「ベースアドレス + 4 × インデックス」で一瞬でアクセス可能。

3. 配列の操作と計算量(本棚イメージ付き)

操作 時間計算量 補足 本棚でのイメージ
値の取得 O(1) インデックスで即座にアクセス 本棚の何段目かを直接指定して本を取る
値の更新 O(1) 同じくインデックスで即座 指定した段の本を別の本に置き換える
値の追加 O(n) 新しい配列を作り、全コピーが必要 本棚を一回まるごと大きい棚に作り替えて全ての本を移動
値の削除 O(n) 同上 本棚の段を一段取り外して全ての本を移動
線形探索 O(n) 順番に調べる 端から順に本を一冊ずつ確認して目的の本を探す
二分探索 O(log n) ソート済みなら半分ずつ範囲を絞れる 本を背表紙の順に並べて、半分ずつ探していく

4. 操作をコードで体感

値の取得・更新は一瞬

int[] scores = {70, 85, 90};
scores[1] = 95; // 更新
System.out.println(scores[1]); // → 95
System.out.println(scores[2]); // → 90

追加・削除は重い

int[] scores = {1, 2, 3};
long start = System.nanoTime();

// 100万件追加のために新しい配列を作る
int[] newScores = new int[scores.length + 1000000];
for(int i = 0; i < scores.length; i++) newScores[i] = scores[i];

long end = System.nanoTime();
System.out.println("コピーにかかった時間: " + (end-start)/1e6 + " ms");

探索のコツ

線形探索(順番に調べる)はO(n)。

int[] scores = {70, 85, 90, 95};
int target = 90;
for(int i = 0; i < scores.length; i++){
    if(scores[i] == target){
        System.out.println(target + " はインデックス " + i + " にあります");
    }
}

ソート済みなら 二分探索(O(log n)) で効率的に絞れます。

import java.util.Arrays;
int[] scores = {10, 20, 30, 40, 50};
int pos = Arrays.binarySearch(scores, 30);
System.out.println("30 はインデックス " + pos + " にあります");

5. 配列を実務でどう理解するか

  • 得意な場面

    • 高速アクセスが必要な計算・シミュレーション
    • 固定サイズのデータ管理(曜日、月別売上など)
  • 苦手な場面

    • 頻繁な追加・削除が発生する動的データ
    • 大量データでコピーコストが無視できない場合
  • 補助的に覚えておくとよいこと

    • Javaでは ArrayList が動的配列、LinkedList が連結リスト
    • 配列の固定長・連続メモリの性質を理解していれば、これらの選択肢の意味が腑に落ちる

6. まとめ

配列は単なる「同型の箱」ではなく、コンピュータの低レイヤ構造と密接に関わったデータ構造です。

  • 連続メモリによりランダムアクセスが高速
  • 固定長・同型により効率的に管理可能
  • 追加・削除はコストがかかるため用途を選ぶ

配列の特徴を体感し、なぜそう設計されているかを理解することは、他のデータ構造や実務上の選択肢を理解する上でも重要です。

GitHubで編集を提案

Discussion