Java
2021.11.19
Java配列の使い方まとめ!初期化や宣言・要素の追加方法を学ぼう【入門編】
2023.11.15

1.Javaの配列とは

配列とは、同じ型の複数ある値をまとめて一つとして扱うことができるものです。配列の中に格納された値は要素と呼ばれます。配列の要素は順番に並べられていて、特定の要素を書きかえたり取り出したりもできます。プログラミングを行うにあたって配列は基本的な文法であり、Java以外のPythonやPHPなどのあらゆるプログラミング言語で使用されます。

複数名のデータ、年齢や身長などを集計するような場合、Aさんの年齢、Bさんの年齢…とそれぞれに変数を作成して数字を代入していくよりも、それぞれのデータを1つの配列として宣言し扱う方がソースコードを書きやすく、データとしても扱いやすいです。

例えば以下のように、一つの配列の中に3人分のデータを順番に格納することで、配列を使わずに書いた場合3行になるコードを、たった1行で書けます。データ量が増えれば増えるほど、配列のメリットも大きくなります。

//3名の年齢をそれぞれの変数に格納する場合;
int a_age = 10;
int b_age = 20;
int c_age = 30;

//3名の年齢を配列に格納する場合
int ages[] = { 10, 20, 30 };

さらに、配列をfor文などの繰り返し処理と組み合わせることもできます。配列を用いずに処理するには時間がかかりすぎて扱いきれない数百、数千といったデータを、簡単に処理できるようになります。システム開発を行っていく上で必ずマスターすべき文法・処理です。

使い方さえ覚えてしまえば配列は難しくなく便利なものです。この記事では配列の使い方や書き方、気をつけるべきポイントなど基礎について解説をしますので、プログラミング初心者の方も配列とはどんなものなのかイメージを掴んでくださいね。


2.  Javaの配列を使用する上での基本ルール


配列を用いる際はいくつか決まった作法がありますが、まずは基本的なルールを二つ覚えておきましょう。

2-1.インデックスで要素にアクセスする

一つ目は、配列の要素にアクセスする際に「インデックス」を用いることです。配列は複数の要素の中で指定した要素に対して値を格納したり、格納した値を参照したりできます。それぞれの要素に対してインデックスと呼ばれる番号を割り当てることで、区別されています。

インデックスは0から始まり、 1, 2, … と順番に割り当てられます。慣れると間違えませんが、最初は1ではなく0から始まることに注意しましょう。配列を宣言して作成した後は、各要素を 配列変数名[インデックス] → ages[0]といったように記載することで、要素に格納されている値を参照できます。

2-2.同じデータ型の値を格納する

二つ目のルールは、同じデータ型を格納することです。Java で配列を利用する時には、変数を利用する時と同様、扱うデータ型を指定して配列を宣言する必要があります。

配列は複数の値をまとめて管理することができますが、格納するデータ型は同じでなければなりません。仮にString型の配列にint型のデータを格納する際には、メソッドなどを利用して要素をキャスト(型変換)する必要があります。

配列が同じ型を格納するものという原則を覚えておくことで、配列を見たときにintならint型の配列を、StringならString型の配列と、自分が書いたソースコードでなくても理解できます。


3.配列の基本的な書き方


配列の基本的な書き方について、ソースコードを交えて宣言方法や初期化など順に見ていきましょう。

3-1. 配列の宣言

まず配列を使用するには、通常の変数の場合と同じように宣言が必要です。

宣言の仕方には、以下の2種類があります。

①データ型 + 変数名 + []

②データ型 + [] + 変数名

本記事では、変数名の後ろに角括弧[]をつける書き方で宣言します。

// 配列の宣言
int nums[];

3-2. 配列の初期化

配列に入れるデータが決まっていない時などは、次のようにして初期化し空の配列を作成しましょう。空の場合でも配列が何個の要素を持つかは指定しないといけません。今回は数字の5を入れているので要素を5つ持てる配列が作成されました。

// 配列の初期化
nums = new int[5];

また以下のように配列の初期化と宣言を同時に行い、ソースコードを省略する書き方もあるので、こちらも是非覚えておきましょう。

// 初期化と宣言を同時に行う書き方
int nums[] = new int[5];

3-3. 配列の代入

空の配列にデータを入れるには、次のようにインデックスを指定して要素を格納していきます。配列の最初のインデックスは1ではなくて0となりますのでこの点は気をつけてください。

// 配列を初期化し、その後代入する書き方

nums = new int[5];
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
nums[4] = 5;

配列への代入の書き方は様々あり、以下のように宣言と同時に代入までしてしまう書き方もあります。このように書くとさらにスッキリして読みやすいコードと言えます。

// 宣言と代入を同時に行う書き方
int nums[] = {1,2,3,4,5};

どちらの書き方でも同じように処理は動きますが、基本的にプログラミングでは行数が少なくて分かりやすいコードが良いとされますので、宣言と代入は同時に行いましょう。

今回の例ではint型のデータを格納していますが、文字列データを格納する場合もやり方は同じで、具体的には以下のようにString型で配列を宣言して記載します。

// 文字列データの配列を作成
String chars[] = {"あ", "い", "う", "え", "お"};

3-4. 配列の参照

配列に格納したデータをコマンドプロンプト(ターミナル)上に出力する際は、以下のようにインデックスを指定して記載していきます。

// 配列の参照
// 配列のインデックス[2]=3番目の要素である3を出力
System.out.println(nums[2]);

以下のようにfor文などの繰り返し構文と組み合わせることで、配列の要素全てに対して指示を与え、順番に要素を出力できます。

// 配列の参照
for(int i=0; i<5; i++){
    System.out.println(nums[i]);            
}


4.配列の便利な使い方

Javaでは予め用意されたクラスやメソッドを使用することで、配列に対して様々な操作ができます。ここでは配列に関連したよく使用される処理を実際のソースコードと一緒に見ていきましょう。

4-1.要素の取得・検索

①lengthで要素数を取得

lengthは配列の要素数を保持するフィールドです。配列名.lengthと書くと、配列の中に要素数がいくつあるのかを返してくれます。

String countries[] = {"アメリカ", "中国", "インド", "ブラジル"};  
System.out.println(countries.length);
// 配列の要素数である4が出力される

②for文と組み合わせて要素を検索

配列をfor文と組み合わせることで、以下のような検索プログラムを作成できます。

for(int i=0; i<countries.length; i++){
    if(countries[i] == "ブラジル"){
        System.out.println("配列の中にブラジルはあります。");
    }
}
// if文内の文章が出力される

③リストに変換してcontainsで検索

配列を先にリストに変換しておく必要はありますが、containsメソッドを使用することで、要素の中に指定した値があるかないかをtrueかfalseで判定できます。

また、本記事では省略しておりますが、Arraysクラスを使う際にはimport java.utils.Arrays;と記載し、クラスをインポートしておく必要があるので気をつけましょう。

if(Arrays.asList(countries).contains("日本")){
    System.out.println("配列の中に日本はあります。");
} else{
    System.out.println("配列の中に日本はありません。");
}
// else文の文章が出力される

4-2.要素の追加・上書き

①インデックスを指定して要素を上書き

String colors[] = {"blue", "red", "green"}; 
colors[2] = "yellow"
// colors → {"blue", "red", "yellow",};

②System.arraycopyで要素を追加

arraycopyは指定したインデックスから配列を書き替え、要素を追加できます。

String old_colors[] = {"blue", "red", "green"};

String new_colors[] = new String[5];
System.arraycopy(old_colors, 0, new_colors, 0, 3);

new_colors[3] = "pink";

new_colors[4] = "purple";
// new_colors → {"blue", "red", "green", "pink", "purple"}

③cloneで要素をコピー

cloneメソッドで配列をコピーできます。

String colors_original[] = {"pink", "purple"};

String colors_new[] = colors_original.clone();

System.out.println(Arrays.toString(colors_new));
// 出力結果→ [pink, purple]

④System.arraycopyで要素をコピー

arraycopyは要素追加だけでなく配列のコピーにも使用できます。

String colors_copied[] = new String[colors_original.length];
System.arraycopy(colors_original, 0, colors_copied, 0, colors_original.length);
// colors_copied → [pink, purple]

⑤Arrays.sortで要素をソート

sortメソッドで配列を並び替えられます。int型の場合は数字の小さい順となります。

Int nums[] = {11, 8, 10, 7};
Arrays.sort(nums);
// nums   →   [7, 8, 10, 11];

4-3.要素の削除

①リストに変換してからremoveで削除する

removeメソッドで配列の要素を削除する際は、事前にリストへの型変換が必要です。

String hiragana_array[] = { "あ", "い", "う", "え", "お" };
List<String> hiragana_list = 
new ArrayList<String>(Arrays.asList(hiragana_array));
hiragana_llist.remove("う")
// hiragana_list   →   [あ, い, え, お]

4-4.配列の操作

①String.joinで配列を文字列に変換

joinメソッド第一引数を区切り文字として、配列を一つの文字列に変換できます。

String hiragana[] = {"か", "き", "く", "け", "こ"};
String hiragana_string = String.join("/", hiragana);
// hiragana_string →  か/き/く/け/こ

②System.arraycopyで配列の結合

arraycopyを利用して配列を結合することもできます。

String hiragana1[] = {"か", "き", "く"};
String hiragana2[] = {"け", "こ"};
String hiragana3[] = new String[hiragana1.length + hiragana2.length];
System.arraycopy(hiragana1, 0, hiragana3, 0, hiragana1.length);  
System.arraycopy(hiragana2, 0, hiragana3, hiragana1.length, hiragana2.length); 
System.out.println(Arrays.toString(hiragana3);
// 出力結果→ [か, き, く, け, こ]



5.配列とリスト

5-1.リストとは

Javaには複数の値を保持する方法として、コレクション・フレームワークというものが用意されています。その中に「リスト」という配列に似た機能が存在します。

Javaを初めて学ぶ際には『コレクション』『ArrayList』『マップ』『配列』など様々な言葉があり特徴も少しずつ違うので特に初心者の方は混乱しやすいです。最初に全てを理解しなくても使っていくうちに分かることも増えていきますので、焦らず慣れていきましょう。

上の図は、Javaで複数の値を管理できるコレクション・フレームワークのクラス図です。真ん中の行のリストやセットはインターフェイスという設計図のようなもので、このインターフェイスを継承して実際にインスタンスとして要素を格納できるクラスが、その下にあるArrayListやLinkedListなどです。

詳細は割愛しますが、リストはインデックスを利用して要素に素早くアクセスできるのが特徴で、配列に似た形は持っていますが、自由に要素を追加したりListに備わった便利なメソッドを使用したりできる点が異なります。

5-2.配列とリストの違い

配列の要素数を決めた後に、配列を後から追加する場合はどうなるのでしょうか。

int nums[] = new int[5];
nums[5] = "6";

上記のコードでは、ArrayIndexOutOfBoundsExceptionのエラーが発生し、不正(元々想定していない)なインデックスで配列にアクセスしようとしているとJavaに怒られます。

配列とリストの違いで、最初に上がるのは固定長と可変長の違いで、簡単に言うと要素数を変更できるかどうかと言う点です。

また、リストはjava.utilパッケージの中にあるクラスで、以下のようにクラスをimportして使います。<>の部分には型クラスを設定しますが、ラッパークラスしか指定できないため「int」ではなく「Integer」と記述する必要があります。ラッパークラスについて詳しくは割愛しますが、ここでは便利なメソッドを扱えるように変換された型と考えるとイメージしやすいはずです。

import java.util.List;
import java.util.ArrayList;
List<Integer> num_list = new ArrayList<Integer>();

5-3.配列とリストの変換方法

4-3でも出てきましたが、配列からリストに変換するにはArrays.asListメソッドを使用します。Arraysクラスの中にあるasListメソッドを使うことで配列からリストに変換できます。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

String array[] = {"あ", "い", "う", "え", "お"};
List<String> list = new ArrayList<String>(Arrays.asList(array));
list.add("か");
System.out.println(list);
// 出力結果→ [あ, い, う, え, お, か]



6.多次元配列について

6-1.多次元配列とは

配列にはこれまで数値や文字列を格納することを紹介してきましたが、複数の配列を格納することもできます。配列を格納した配列を二次元配列と呼びます。

もう一つ次元が増えると二次元配列を複数個持つ三次元配列となり、理論上はN次元と入れ子式に次元を増やせます。

6-2.多次元配列の書き方

Javaで多次元配列を作成する場合、基本的な書き方は配列と似ていますが、[]の数が次元分増えます。

例えば二次元配列の場合は、以下のように作成できます。適宜改行やインデント等を用いると入れ子であることが視覚的に認識でき、後からソースコードを見た際にも配列の構造が一目で分かりやすいですね。

String array[][]  = {
{ "あ", "い", "う", "え", "お"},
{ "か", "き", "く", "け", "こ"},
{ "さ", "し", "す", "せ", "そ"},
{ "た", "ち", "つ", "て", "と"},	
};

配列にアクセスする時も、入れ子のインデックスを順番に選択することで各要素を使用できます。二次元配列のうち3番目の配列は[2]、その中で更に4番目の要素は[3]なのでarray[2][3]と書くことでアクセスできます。このように配列の次元が増えると複雑さは増しますが、要素を指定するインデックスのルールは変わらないことを知っておけば、多次元配列に実際に出会った時でも慌てず対処できるはずです。

System.out.println(array[2][3]);
// 出力結果→「せ」



7.配列を扱う上で気をつけるべきポイント


最後に、配列を使う上で気をつけるべきことなどを説明します。

7-1.配列は要素数を超えて値を格納することはできない

リストの説明の中で触れたので詳細は割愛しますが、配列は要素数を超えて値を格納することはできません。

可変的な変数を利用する際は要素数を変更できる「コレクション・フレームワーク」を利用するなどして、別のクラスにキャスト(型変換)してからソースコードを書いていくとエラーを超えて先に進めるでしょう。

7-2.ラッパークラスとプリミティブ型の違いに気をつける

配列にプリミティブ(値型)であるintのデータを格納した際には、値型はメソッドも持たないため、配列の要素に対してint型の変数.メソッド名()のような呼び出し方はできません。最大値・最小値を取得するといった様々な便利なメソッドを扱うにはあらかじめラッパークラスであるIntegerクラスに変換することが必要となります。

値型にメソッドを加えてオブジェクトとして使用できるよう変換するのがラッパークラスです。ここでは詳細は省きますので、気になる方はラッパークラス・プリミティブ(値)型などで検索して頂ければと思います。


[参考記事]Java ラッパークラスとは (intとIntegerの違い)

https://itsakura.com/java-wrapper-class

7-3.配列は参照型

Javaにはint型やString型など様々な型がありますが、これらは基本データ型と参照型に分かれます。

基本データ型には8つあり、boolean型は1bit、int型は32bitというように必要なbit数が決まっていて、値を直接保持するのが特徴です。

一方、値そのものを保持するのではなく、値が置いてある場所を保持するのが参照型で、配列もこれにあたります。基本データ型と参照型のどちらの型への代入が行われているかで、その後の処理の結果が変わることがあります。

以下の例を見てみましょう。

//基本データ型への代入
int a = 1;
int b = a;
b = 2;
System.out.println(a);
// 1が出力される。

基本データ型はこのようにaが1を持ち続けますが、

これに対して参照型の配列で似たような処理を行うとどうなるでしょうか。

int array_a[] =  {1};
int array_b[] =  array_a;
array_b[0] = 2;
System.out.println(array_a[0]);
//2が出力される。

参照型の場合、array_bを宣言しても参照先は増えません、array_a[0]もarray_b[0]も同じ値を参照しているため、参照している先の値が変更されればどちらも新しい値に置き換わります。

このように、Javaでは値を更新する際に更新している型が何なのかを気をつける必要があります。

以上、この記事ではJavaでの配列について基礎的な事から順番に説明してきましたが、筆者としては分厚い参考書などを何冊も読むよりは文法や仕組みはさらりと理解して、開発やハンズオン形式などで手を動かしながら勉強することをお勧めします。


この記事をシェア