配列の基本
配列は、同じ種類のデータを複数まとめて管理するための仕組みです。
例えば、動物の名前を5つ保存したいとき、animal1、animal2、animal3...と変数を5つ作るのは大変です。こういうときに配列を使えば、まとめて1つの「入れ物」として扱えます。
ここでは、配列の基本的な特徴から、宣言方法、初期化、要素数の取得まで、順を追って解説していきます。
配列の特徴
配列には、いくつかの重要な特徴があります。基本的な3つの特徴を押さえておきましょう。
1つ目に、配列に入れられるのは「同じデータ型」の値だけです。整数の配列なら整数だけ、文字列の配列なら文字列だけが入ります。
2つ目に、配列は一度作ると大きさが変わりません。
最初に「5個入る配列」と決めたら、後から6個目を追加することはできません。これを「固定長」といいます。
3つ目に、配列の各要素には「インデックス」という番号が付いています。この番号は0から始まります。5個の要素がある配列なら、0、1、2、3、4という番号でアクセスします。
出力結果
10
50numbers[0]で最初の要素(10)を、numbers[4]で最後の要素(50)を取り出しています。
インデックスは0から始まるため、5個の要素がある配列の最後はnumbers[4]で指定する点に注意です。
配列の宣言方法
Javaで配列を宣言する方法は2種類あります。具体的には次のような書き方です。
- int[] array
- int array[]
どちらも機能的には同じですが、int[] arrayの書き方が推奨されています。
なぜかというと、この書き方のほうが「int型」かつ「配列」であることが明確にわかるからです。特に、複数の配列を同時に宣言するときに読みやすくなります。
int[] lions, tigers;と書けば、lionsもtigersも両方とも配列だということが一目でわかります。
もし、int lions[], tigers;と書いた場合は、lionsだけが配列として見なされます。
配列の初期化
配列を使うには、宣言した後に「初期化」という作業が必要です。初期化の方法は主に2つあります。
1つ目は、最初から具体的な値を入れる方法です。波括弧{}の中に値を並べて書きます。
2つ目は、newを使って「何個入る配列」かを指定する方法です。
この場合、最初は空っぽの状態で作られ、各要素には初期値が自動的に入ります。数値型なら0、文字列型ならnullが入ります。
出力結果
animals2[0]: null
scores[0]: 0要素数の取得
配列に何個の要素が入っているかを知りたいときは、lengthを使います。
注意点は、メソッドではなくプロパティなので、lengthは括弧()を付けないということです。array.lengthのように書きます。
このlengthは、配列をループで処理するときによく使います。
出力結果
配列の長さ: 3
ハムスター
インコ
カメpets.lengthで要素数(3)を取得し、その回数分だけループを回して全ての要素を表示しています。
また、i < pets.lengthという条件により、配列の範囲を超えてアクセスすることを防いでいます。
配列操作と文字列との関連
配列の基本を理解したら、次は実際にどう使うかを学びましょう。
ここでは、配列の値を変更する方法や配列と文字列の関係について解説します。特に文字列と配列の相互変換は、実際のプログラミングでよく使う技術です。
要素の更新
配列に入っている値は、後から変更できます。
変更したい要素のインデックスを指定して、新しい値を代入するだけです。ただし、存在しないインデックスを指定するとエラーになるので注意しましょう。
出力結果
トラインデックス1(2番目)の要素を「ゾウ」から「トラ」に変更しています。
もし、zoo[5] = "パンダ";のようなコードを実行すると、配列は3個しか要素がないのに5番目にアクセスしようとするため、ArrayIndexOutOfBoundsExceptionというエラーが発生します。
配列に追加できない理由
Javaの配列には、後から要素を追加することができません。
なぜかというと、配列は作成時に決めた大きさが固定されるからです。これを「固定長」といいます。もし要素を増やしたい場合は、新しく大きな配列を作り、古い配列の内容をコピーする必要があります。
この仕組みのおかげで、配列はメモリを効率よく使えます。しかし、柔軟にサイズを変えられないという制限もあります。
出力結果
ウシ
ブタ
ニワトリこの例では、2個の要素を持つ配列から、3個の要素を持つ新しい配列を作っています。元の2つの要素をコピーした後、3番目に新しい要素を追加しています。
サイズを自由に変更したい場合は、配列ではなくArrayListという別の仕組みを使うことをおすすめします。
文字列とchar配列
文字列は、実は内部的に「文字の配列」として管理されています。
toCharArray()というメソッドを使うと、文字列を文字の配列に変換できます。変換すると、文字列の一文字一文字に個別にアクセスできるようになります。
出力結果
文字数: 2
ウ
マ「ウマ」という文字列を文字の配列に変換しています。変換後の配列には、'ウ'と'マ'という2つの文字が別々の要素として入っています。
この技術は、文字列を一文字ずつ処理したいときに便利です。例えば、文字列を逆順にしたり、特定の文字を数えたりする処理で活用できます。
文字列配列の活用
文字列を複数まとめて管理したいときは、文字列の配列を使います。
実際の開発では、設定値のリスト、メニューの選択肢、ユーザーからの入力データなど、さまざまな場面で使われます。
特にmainメソッドの引数String[] argsは、プログラム実行時に渡されるパラメータを受け取るための文字列配列です。
出力結果
動物メニュー:
- サル
- イノシシ
- シカ3つの動物名を配列に入れ、拡張for文で一つずつ取り出して表示しています。
for (String item : menu)という書き方は「menuの中の要素を一つずつitemに入れて処理する」という意味です。
この拡張for文は、コレクション(配列やリストなど、要素の集まり)のすべての要素を順番に取り出して処理したい場合に非常に便利です。
ぜひ、この機会に覚えておきましょう。
二次元配列の仕組みと使い方
実はこれまで学んできた配列は、一列にデータが並ぶ「一次元配列」でした。
ここでは、二次元配列の構造、初期化、使い方を順に見ていきましょう。
二次元配列を使うと、表のような「行と列」の形でデータを管理できます。特に、ゲームの盤面、座席表、成績表など、縦横にデータが並ぶ場面で威力を発揮します。
二次元配列の構造
二次元配列は「配列の中に配列が入っている」構造です。
外側の配列が「行」を表し、その中に入っている配列が「列」を表します。イメージとしては、縦に並んだ箱(行)があり、それぞれの箱の中にまた横に並んだ小箱(列)が入っている感じです。
このとき、各行の列数が違っていても問題ありません。1行目は3列、2行目は2列、3行目は4列、といった不揃いな配列も作れます。
出力結果
2行目の要素数: 2
table[2][3]: 9このプログラムでは、1行目に3個、2行目に2個、3行目に4個の要素がある二次元配列を作っています。
table[1].lengthで2行目(インデックス1)の{4, 5}の要素数を取得し、table[2][3]で3行目(インデックス2)の4番目の要素(インデックス3)にアクセスしています。
インデックスの番号と行数が1つズレている点には注意しましょう。
二次元配列の初期化
二次元配列の初期化方法も、一次元配列と同じく2種類あります。
1つ目は、波括弧を使って具体的な値を直接書く方法です。外側の波括弧が行を表し、内側の波括弧が列を表します。
2つ目のnewを使う方法では、new int[行数][列数]という書き方で、配列の形を指定します。この場合、全ての要素は初期値(数値なら0、文字列ならnull)で埋められます。
出力結果
ネコanimals1は2行3列の空の配列を作り、animals2は最初から値を入れた2行3列の配列を作っています。
animals2[0][1]で、1行目の2番目の要素(ネコ)を取り出しています。
二次元配列のループ処理
二次元配列の全ての要素を処理するには、ループを2重にします。
外側のループで行を一つずつ処理し、内側のループで各行の列を一つずつ処理します。
イメージは、本棚です。上の段から本を一つずつ取り出していき、その段の本をすべて取り出したら次の段に移動します。
行(段)ごとに列数(本の数)が違う場合でも、array[i].lengthを使えば安全に処理できます。
出力結果
ライオン トラ
ゾウ
キリン シマウマ サイこのプログラムでは、外側のループでiを使って行を処理し、内側のループでjを使って列を処理しています。各行の要素を横に並べて表示した後、println()で改行しています。
行ごとに列数が違うため、内側のループの条件をzoo[i].lengthにすることで、各行の実際の列数だけループを回していることも重要なポイントです。
二次元配列の利用例
二次元配列は、位置や座標を扱うプログラムでよく使われます。
例えば、ゲームのキャラクター位置、地図上の座標、表形式のデータなど、2つの数値で位置を表す場面で便利です。行列計算やデータ分析でも重要な役割を果たします。
出力結果
イヌの位置: (0, 0)
ネコの位置: (3, 4)
ウサギの位置: (-2, 5)3匹の動物それぞれの座標を二次元配列で管理しています。
各動物の名前と座標をセットで表示することで、「どの動物がどこにいるか」をわかりやすく示しています。
配列の応用操作
配列の基本的な使い方をマスターしたら、より実践的な操作を学びましょう。
ここでは、配列のコピー、ソート(並べ替え)、検索といった応用的な操作について解説します。
Javaが用意している便利なメソッドを使うことで、こういった操作を簡単に実現できます。
実際の開発でよく使う技術なので、しっかり身に付けましょう。
配列のコピー方法
配列をコピーする方法はいくつかあります。
clone()メソッドを使うと、元の配列と同じ内容の新しい配列を作れます。Arrays.copyOf()を使えば、コピーする長さを指定できます。元より長い長さを指定すれば、余った部分には初期値が入ります。
注意点として、これは「浅いコピー」と呼ばれる方法です。配列の中身が数値や文字列なら問題ありませんが、自作したオブジェクトの配列をコピーした場合、少し複雑になります。
浅いコピーでは、配列の中身(オブジェクトそのもの)は複製されず、元のオブジェクトへの「参照」(アドレス)だけがコピーされます。したがって、コピー後の配列から要素の中身を変更すると、元の配列の要素も同時に変わってしまう危険性があるため、注意が必要です。
最初のうちは、難しいと思いますので、「浅いコピー」の理解に留めておく形で問題ありません。
出力結果
[イヌ, ネコ, ウサギ, null, null]元の配列を5個の長さでコピーしています。元の配列は3個なので、4番目と5番目にはnullが入ります。
後述しますが、Arrays.toString()を使うと、配列の中身がわかるように表示できます。
ちなみに、配列(または一般的なオブジェクト)をSystem.out.println()でそのまま出力すると、配列の内容ではなく「配列がメモリ上のどこにあるか」を示す情報が出力されてしまいます。
配列のソート
配列の要素を順番に並べ替えることを「ソート」といいます。Arrays.sort()メソッドを使えば、簡単にソートできます。数値なら小さい順、文字列なら辞書順(五十音順、ABC順)に並びます。
重要な注意点は、このメソッドは元の配列自体を変更してしまうことです。元の順番を残しておきたい場合は、先にコピーを作ってからソートしましょう。
出力結果
ソート後: [イヌ, ウサギ, ネコ, ゾウ]ソート後、配列の中身は「イヌ、ウサギ、ネコ、ゾウ」の順に変わっています。動物名を五十音順に並べ替えていることがわかりますね。
配列の検索
配列の中から特定の値を探すには、Arrays.binarySearch()メソッドが使えます。このメソッドは、「二分探索」という効率的な方法で検索を行います。二分探索を使うには、配列が事前にソートされている必要があります。
値が見つかると、そのインデックスを返しますが、見つからなければ負の数を返します。
出力結果
ソート後: [イヌ, ウサギ, ゾウ, ネコ]
ネコのインデックス: 3この例では、まず配列をソートしてから「ネコ」を検索しています。ソート後の配列では「ネコ」は4番目(インデックス3)にあるため、2が返されます。
ソートせずに検索すると正しい結果が得られないので、必ず先にソートすることを忘れないでください。
ちなみに、なぜソートが必要になるかというと、二分探索の検索の仕組みに原因があります。その手順は次の通りです。
- 中央の要素を確認する
- 探している値が、中央の要素より大きいか、小さいかを比較する
- 比較結果に応じて、配列の前半または後半のどちらかを捨てて、残った半分の領域に絞り込む
- この手順を繰り返すことで、検索する範囲を毎回半分に絞り込み、非常に速く目的の値を見つける
この流れを見ると、ソートが必要な理由がわかりますね。
配列で使える便利なメソッド
Arraysクラスには、他にも便利なメソッドがたくさん用意されています。
例えば、次のようなメソッドです。
- toString()は配列の中身を文字列として見やすく表示する
- fill()は配列の全ての要素を指定した値で埋める
- equals()は2つの配列の中身が同じかどうかを比較する
こういったメソッドを使いこなせると、配列の操作がとても楽になります。
出力結果
[ハムスター, ハムスター, ハムスター]
配列が同じ: trueこのプログラムでは、fill()で配列の全ての要素を「ハムスター」で埋めています。
その後、equals()で別の配列と比較し、中身が同じかどうかを確認しています。
よくある質問(Q&A)
Q: 配列のサイズを後から変更できませんか?
A: Javaの配列は固定長のため、作成後のサイズ変更はできません。サイズを変更したい場合は新しい配列を作成し、既存の要素をコピーする必要があります。動的にサイズを変更したい場合はArrayListの使用を検討しましょう。
Q: 配列の最後の要素にアクセスする方法は?
A: array[array.length - 1]で最後の要素にアクセスできます。lengthは要素数を表すため、インデックスとして使用する際は1を引く必要があります。
Q: 二次元配列で行数と列数を取得するには?
A: 行数はarray.length、特定行の列数はarray[行番号].lengthで取得できます。各行の列数が異なる場合があるため、列数は行ごとに確認する必要があります。
Q: 配列をArrayListに変換できますか?
A: Arrays.asList()メソッドを使用することで、配列をListに変換できます。ただし、この方法で作成されるListは固定長のため、要素の追加や削除はできません。
まとめ
配列は、同じ種類のデータをまとめて管理するための基本的な仕組みです。
この記事では、配列の基礎から応用まで、幅広く解説してきました。最後に、重要なポイントを振り返りましょう。
配列の重要なポイント
-
宣言はint[] array形式が推奨
こうすることで、型と配列であることが明確にわかります。 -
サイズは固定である
作成後に要素を追加したり、サイズを変更したりすることはできません。 -
インデックスは0から始まる
例えば、5個の要素がある配列なら、0から4までの番号でアクセスします。 -
lengthで要素数を取得できる
配列の長さを知りたいときはarray.lengthを使います。 -
二次元配列で表形式のデータを管理できる
行と列の概念で、より複雑なデータ構造を表現できます。 -
配列を操作するときにはArraysクラスが便利
ソート、検索、コピーといった操作を簡単に行うことができます。
配列は、プログラミングの基礎中の基礎です。最初は少し難しく感じるかもしれませんが、実際に手を動かしてコードを書くことで、徐々に理解が深まります。
基本的な一次元配列から始めて、二次元配列、応用操作と、段階的に学習していけば、必ず使いこなせるようになるはずです。
実際の開発では、配列を使ってデータを効率的に管理することが頻繁にあります。この記事で学んだ内容を活かして、より実用的なプログラムを作っていきましょう。