Javaプログラミングにおいて、データの集合を扱う際に最も基本的かつ頻繁に使用されるデータ構造が「配列」です。

配列を利用する上で、「配列の中にいくつの要素が格納されているか」を正確に把握することは、ループ処理やデータのバリデーションを行うために欠かせません。

Javaでは配列の要素数を取得するためにlengthという仕組みが用意されていますが、初心者の方にとっては「メソッドなのかフィールドなのか」、あるいは「Listのsize()と何が違うのか」といった点が混同されやすい部分でもあります。

本記事では、Javaプログラミングの基礎である配列の要素数を取得する方法について、基本的な使い方から多次元配列での応用、さらにはCollectionフレームワークとの違いまで、テクニカルな視点で詳しく解説します。

Java配列の要素数(長さ)を取得する基本:length属性

Javaにおいて、配列の要素数を取得するにはlength属性を使用します。

これはメソッドではなく、配列オブジェクトが持つパブリックな読み取り専用フィールドとして定義されています。

length属性の基本的な使い方

配列を作成すると、そのインスタンスには自動的にlengthという変数が備わります。

これにアクセスすることで、配列の宣言時に指定した「確保された領域の数」を取得できます。

以下のサンプルコードで、基本的な記述方法を確認しましょう。

Java
public class ArrayLengthBasic {
    public static void main(String[] args) {
        // 要素数5の整数型配列を宣言
        int[] numbers = {10, 20, 30, 40, 50};

        // length属性を使用して要素数を取得
        int arraySize = numbers.length;

        System.out.println("配列の要素数は: " + arraySize);

        // ループ処理での典型的な活用例
        for (int i = 0; i < numbers.length; i++) {
            System.out.println("インデックス " + i + " の値: " + numbers[i]);
        }
    }
}
実行結果
配列の要素数は: 5
インデックス 0 の値: 10
インデックス 1 の値: 20
インデックス 2 の値: 30
インデックス 3 の値: 40
インデックス 4 の値: 50

length属性はメソッドではない

Javaの文字列(String型)で文字数を取得する際はlength()というメソッドを呼び出しますが、配列の場合は丸括弧 () を付けない点に注意してください。

配列のlengthは特別なフィールドとして扱われるため、メソッド呼び出しのオーバーヘッドがなく、非常に高速にアクセスできるという特徴があります。

また、このlength属性はfinal(変更不可)なプロパティです。

プログラムの実行途中で配列のlengthに値を代入して、配列のサイズを強制的に変更することはできません。

Javaの配列は生成時にサイズが固定される「静的」な性質を持っているためです。

多次元配列における要素数の取得

Javaの多次元配列は「配列の配列」として実装されています。

そのため、多次元配列に対してlengthを使用する場合、どの階層の要素数を取得しているのかを意識する必要があります。

2次元配列の行数と列数を取得する

2次元配列において、単純に配列名.lengthと記述した場合は「行の数」が返されます。

各行(各要素としての配列)の長さを取得したい場合は、配列名[インデックス].lengthのように記述します。

Java
public class MultiArrayLength {
    public static void main(String[] args) {
        // 3行4列の2次元配列
        int[][] matrix = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}
        };

        // 行数の取得
        int rows = matrix.length;
        System.out.println("行数: " + rows);

        // 各行の列数の取得(0行目を代表として取得)
        int cols = matrix[0].length;
        System.out.println("列数: " + cols);

        // すべての要素をループで表示
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }
}
実行結果
行数: 3
列数: 4
1 2 3 4 
5 6 7 8 
9 10 11 12

ジャグ配列(不揃いな配列)の場合

Javaでは各行の要素数が異なる「ジャグ配列(不規則配列)」を作成することも可能です。

この場合、それぞれの行に対してlengthを確認することで、安全に要素へアクセスできます。

Java
public class JaggedArrayExample {
    public static void main(String[] args) {
        int[][] jagged = new int[3][];
        jagged[0] = new int[2];
        jagged[1] = new int[5];
        jagged[2] = new int[3];

        for (int i = 0; i < jagged.length; i++) {
            System.out.println(i + "行目の要素数: " + jagged[i].length);
        }
    }
}

このように、多次元配列ではlengthが入れ子構造になっていることを理解しておくことが重要です。

lengthとsize()、length()の違いを徹底比較

Javaには「長さ」や「サイズ」を取得するための似たような表現が複数存在します。

これらを正確に使い分けることは、コンパイルエラーを防ぐための第一歩です。

以下の表に、主要なデータ型における要素数取得方法をまとめました。

対象オブジェクト取得方法種類説明
配列 (Array)lengthフィールド配列生成時に固定された要素数を取得する
文字列 (String)length()メソッド文字列に含まれる文字数を取得する
リスト (ArrayList等)size()メソッドコレクションに格納されている現在の要素数を取得する
マップ (HashMap等)size()メソッドマップに含まれるキーと値のペア数を取得する

length と size() の決定的な違い

最も混同しやすいのが、配列のlengthと、ArrayListなどで使われるsize()です。

メモリ確保か実データ数か

配列のlengthは、生成時に確保したメモリ領域の数を示します。

例えば new int[10] と宣言すれば、中に値を入れなくてもlengthは常に10です。

一方、Listsize()は、現在そのリストに実際に格納されている要素の数を返します。

動的変更の可否

配列のサイズは固定ですが、Listは要素を追加・削除するたびにsize()の結果が動的に変化します。

記述ルール

配列はフィールドアクセス(括弧なし)、コレクションはメソッド呼び出し(括弧あり)という構文上の違いがあります。

length と length() の使い分け

初心者がよく陥るミスとして、配列に対してarray.length()と記述してしまうケースがあります。

これは「シンボルを見つけられません」というコンパイルエラーの原因となります。

逆に、String型に対してstr.lengthと書くこともできません。

「配列は特殊なオブジェクトなのでフィールド参照、Stringはクラスなのでメソッド呼び出し」と覚えておくと良いでしょう。

配列の要素数を扱う際の注意点とエラー対策

配列の要素数を扱う際には、実行時に発生する可能性のあるいくつかの例外(Exception)に注意を払う必要があります。

ArrayIndexOutOfBoundsException(インデックス範囲外例外)

Javaの配列インデックスは0から始まります

そのため、アクセス可能な最大インデックスは「length – 1」となります。

Java
int[] data = new int[5];
// data.length は 5 ですが、有効なインデックスは 0, 1, 2, 3, 4 です。
// 以下のコードは実行時に例外を投げます。
System.out.println(data[5]);

このエラーを防ぐためには、ループの継続条件をi < data.lengthとする、あるいは拡張for文(enhanced for loop)を使用することが推奨されます。

拡張for文を使用すれば、インデックスを意識することなく安全に全要素へアクセス可能です。

NullPointerException(ぬるぽ)

配列変数がnullで初期化されている場合、lengthを参照しようとするとNullPointerExceptionが発生します。

Java
int[] values = null;
// values が null なので、length にアクセスできない
if (values != null && values.length > 0) {
    System.out.println("配列は空ではありません");
}

外部からの入力やメソッドの戻り値として配列を受け取る場合は、lengthを確認する前に必ずnullチェックを行うのが安全なコーディングの定石です。

空の配列と要素数0

Javaでは「要素数0の配列」を作成することも可能です。

これはnullとは異なります。

new int[0] で生成された配列のlengthは 0 です。

要素を1つも持たないものの、配列オブジェクト自体は存在するため、メソッドの戻り値として「該当データなし」を表現する際によく使われます(nullを返すよりも安全な設計とされます)。

要素数取得の応用:動的な処理とStream API

Java 8以降で導入されたStream APIを使用すると、配列の要素数に基づいた高度な操作が容易になります。

単純なlengthだけでなく、条件に合致する要素の数だけを数えるといった処理もスマートに記述できます。

条件に一致する要素数をカウントする

通常のlengthは全要素数を返しますが、特定の条件(例:偶数のみ、特定の文字列を含む等)を満たす要素の数を知りたい場合は、Arrays.stream()を活用します。

Java
import java.util.Arrays;

public class ArrayStreamCount {
    public static void main(String[] args) {
        int[] numbers = {1, 5, 8, 12, 15, 20, 7, 30};

        // 10以上の値を持つ要素の数をカウント
        long count = Arrays.stream(numbers)
                           .filter(n -> n >= 10)
                           .count();

        System.out.println("全要素数: " + numbers.length);
        System.out.println("10以上の要素数: " + count);
    }
}
実行結果
全要素数: 8
10以上の要素数: 4

配列のコピーとリサイズ

配列の要素数が足りなくなった場合、既存の配列を「拡張」することはできません。

代わりに、より大きなlengthを持つ新しい配列を作成し、中身をコピーする必要があります。

これにはArrays.copyOf()が便利です。

Java
int[] original = {1, 2, 3};
// 要素数を5に増やした新しい配列を作成(元の要素を引き継ぐ)
int[] extended = java.util.Arrays.copyOf(original, 5);

System.out.println("新しい配列の長さ: " + extended.length);

このように、lengthは単に参照するだけでなく、新しい配列を構築する際の基準値としても頻繁に利用されます。

まとめ

Javaにおいて配列の要素数を取得するlengthは、非常にシンプルながらもプログラミングの根幹を支える重要なプロパティです。

本記事で解説したポイントを改めて整理します。

  • 配列の要素数は「length」フィールドで取得する(メソッドではないため丸括弧は不要)。
  • Stringの「length()」やListの「size()」と混同しないよう注意が必要。
  • 多次元配列では「階層ごとの要素数」を取得するため、インデックス指定を適切に行う。
  • インデックスは0から始まるため、最大インデックスは常に length - 1 である。
  • nullの配列に対してlengthを参照すると例外が発生するため、nullチェックを怠らない。

配列のサイズ管理を正しく理解することは、メモリ効率の良い、かつバグの少ない堅牢なコードを書くための第一歩です。

特にループ処理やデータのフィルタリングにおいては、lengthを起点とした制御が基本となります。

今回学んだ内容を活かして、より正確な配列操作をマスターしてください。