この記事では、Javaにおける配列の基本から応用まで、解説します。配列の宣言と初期化の方法、主要な特徴、そしてJava 8以降で導入されたStream APIとラムダ式を用いた配列操作まで学ぶことができます。
はじめに
この記事のコードをコピペしてEclipseで出力結果を確認してみよう!
配列の宣言と初期化
配列は、同じデータ型の複数の要素をまとめて扱うためのデータ構造です。配列の宣言と初期化には主に2つの方法があります。
new演算子を使用する方法
データ型[] 配列名 = new データ型[要素数];
この方法では、配列のサイズを指定して新しい配列オブジェクトを作成します。
例:
int[] numbers = new int[5]; // 5つの整数を格納できる配列を作成
この方法で宣言された配列は、各要素がそのデータ型のデフォルト値で初期化されます。
初期化子リストを使用する方法
データ型[] 配列名 = {要素1, 要素2, ...};
この方法では、配列の宣言と同時に要素を指定して初期化します。
例:
String[] fruits = {"apple", "banana", "orange"}; // 3つの文字列要素を持つ配列を作成
配列の主要な特徴
固定サイズ:
配列のサイズは作成時に決定され、後から変更することはできません。例えば、10要素の配列を作成した場合、11番目の要素を追加することはできません。
型安全性:
配列は宣言時に指定されたデータ型の要素のみを格納できます。例えば、int型の配列にはint型の値のみを格納でき、String型の値は格納できません。
メモリ効率:
配列の要素はメモリ上で連続して配置されるため、メモリアクセスが効率的です。
長さの取得
配列の長さはlength
プロパティを使用して簡単に取得できます。
int[] numbers = new int[5];
System.out.println(numbers.length); // 5を出力
これらの特徴により、配列は同じ型の複数のデータを効率的に管理するのに適したデータ構造となっています。
配列へのアクセス
配列の要素にアクセスするには、配列名とインデックスを使用します。
int[] scores = {85, 90, 78};
System.out.println(scores[1]); // 90を出力
多次元配列
Javaは多次元配列もサポートしています。2次元配列は以下のように宣言できます:
int[][] matrix = new int[3][3]; // 3x3の2次元配
プログラム例
配列の要素の値を出力するプログラムです。
// 整数型の配列を宣言し、初期化
int[] numbers = { 1, 2, 3, 4, 5 };
// 配列の要素を出力
for (int i = 0; i < numbers.length; i++) {
System.out.println("要素 " + i + ": " + numbers[i]);
}
出力結果:
要素 0: 1
要素 1: 2
要素 2: 3
要素 3: 4
要素 4: 5
このプログラムの詳しい解説をします。
- 配列の宣言と初期化:
int[] numbers = { 1, 2, 3, 4, 5 };
int[]
は整数型の配列を宣言することを示します。numbers
は配列の変数名です。{ 1, 2, 3, 4, 5 }
は配列リテラルと呼ばれ、配列の初期値を直接指定します。- この1行で配列の宣言と初期化を同時に行っています。
- for ループの開始:
for (int i = 0; i < numbers.length; i++) {
int i = 0
でループカウンタi
を0で初期化します。i < numbers.length
はループの継続条件です。numbers.length
は配列の長さ(要素数)を返します。i++
は各ループの最後にi
を1増加させます。
- 配列要素の出力:
System.out.println("要素 " + i + ": " + numbers[i]);
System.out.println()
は文字列を出力し、改行します。"要素 "
は固定の文字列です。i
はループカウンタの現在値で、配列のインデックスを表します。numbers[i]
はnumbers
配列のi
番目の要素にアクセスします。+
演算子を使って、文字列と数値を連結しています。
このコードの特徴と重要なポイント:
- 配列の宣言と初期化を1行で行っており、コードが簡潔になっています。
numbers.length
を使用することで、配列のサイズに依存しないループを作成しています。これにより、配列のサイズが変更されても、コードを修正する必要がありません。- インデックスベースのアクセス(
numbers[i]
)を使用して、配列の各要素に順番にアクセスしています。 - 出力では、インデックス(
i
)と要素の値(numbers[i]
)の両方を表示しており、配列の構造を視覚的に理解しやすくなっています。
このコードは、配列の基本的な操作と出力を示す良い例となっています。
プログラム例(応用)
配列を「ソート」や「コピー」するプログラムです。
// Arrays クラスをインポート。配列を操作するための便利なメソッドを提供します。Arrays.sort()などが使用可能
import java.util.Arrays;
public class AdvancedArrayExample {
public static void main(String[] args) {
// 文字列型の配列を宣言
String[] fruits = new String[5];
// 配列に要素を追加
fruits[0] = "りんご";
fruits[1] = "バナナ";
fruits[2] = "オレンジ";
fruits[3] = "ぶどう";
fruits[4] = "メロン";
// 配列の内容を出力
System.out.println("元の配列: " + Arrays.toString(fruits));
// 配列をソート
Arrays.sort(fruits);
System.out.println("ソート後の配列: " + Arrays.toString(fruits));
// 特定の要素を検索
int index = Arrays.binarySearch(fruits, "りんご");
System.out.println("「りんご」のインデックス: " + index);
// 配列のコピー
String[] fruitsCopy = Arrays.copyOf(fruits, fruits.length);
System.out.println("コピーした配列: " + Arrays.toString(fruitsCopy));
}
}
出力結果:
元の配列: [りんご, バナナ, オレンジ, ぶどう, メロン]
ソート後の配列: [ぶどう, りんご, オレンジ, バナナ, メロン]
「りんご」のインデックス: 1
コピーした配列: [ぶどう, りんご, オレンジ, バナナ, メロン]
このプログラムの詳しい解説をします。
- 配列の宣言と初期化:
String[] fruits = new String[5];
5つの要素を持つ文字列型の配列を宣言しています。
- 配列への要素の追加:
fruits[0] = "りんご";
fruits[1] = "バナナ";
// ...
インデックスを指定して各要素に値を代入しています。
- 配列の内容出力:
System.out.println("元の配列: " + Arrays.toString(fruits));
Arrays.toString()
メソッドを使用して配列の内容を文字列として出力しています。
- 配列のソート:
Arrays.sort(fruits);
Arrays.sort()
メソッドを使用して配列を辞書順にソートしています。
- 要素の検索:
int index = Arrays.binarySearch(fruits, "りんご");
Arrays.binarySearch()
メソッドを使用して”りんご”のインデックスを検索しています。このメソッドはソート済みの配列に対してに検索しています。
※インデックスは「0」が「ぶどう」、「1」が「りんご」です。
- 配列のコピー:
String[] fruitsCopy = Arrays.copyOf(fruits, fruits.length);
Arrays.copyOf()
メソッドを使用して配列の完全なコピーを作成しています。
Java 8以降の機能(Stream API)
Stream APIを使用することで、配列操作をより簡潔で読みやすいコードで記述できるようになりました。例えば、配列から条件に合う要素を抽出して処理する場合、従来のfor文とif文の組み合わせよりも、ストリームを使用した方がコードがシンプルになります。
import java.util.Arrays;
public class SimpleArrayStreamExample {
public static void main(String[] args) {
// 1. データソース:整数の配列
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 2. Stream操作:偶数をフィルタリングし、各要素を2倍にする
Arrays.stream(numbers) // 配列からStreamを生成
.filter(n -> n % 2 == 0) // 中間操作:偶数のみをフィルタリング
.map(n -> n * 2) // 中間操作:各要素を2倍にする
.forEach(System.out::println); // 終端操作:結果を出力
}
}
このプログラムの詳しい解説をします。
- データソースの準備:
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- これは通常の整数配列の宣言と初期化です。
- 1から10までの整数を含む配列を作成しています。
- ストリームの生成:
※ストリームは、データの連続した流れを表現します。配列やコレクションなどのデータソースから要素を一つずつ取り出し、一連の処理ステップを通して変換や加工を行っていくイメージです。
Arrays.stream(numbers)
Arrays.stream()
メソッドを使用して、配列からストリームを生成します。- これにより、配列の要素に対して一連の操作を行うことができるようになります。
- フィルタリング操作:
.filter(n -> n % 2 == 0)
filter()
メソッドは中間操作で、条件に合う要素だけを次の段階に渡します。n -> n % 2 == 0
はラムダ式です:
※ラムダ式は(引数) -> { 処理 }
の形式を取ります。n
は配列の各要素を表す引数->
はラムダ演算子で、左側の引数を右側の式に適用することを示しますn % 2 == 0
は偶数かどうかをチェックする条件(2で割った余りが0)- この操作により、偶数の要素のみが次の段階に進みます。
- マッピング操作:
.map(n -> n * 2)
map()
メソッドは中間操作で、各要素を変換します。n -> n * 2
もラムダ式です:n
は前の段階から渡された各要素n * 2
は各要素を2倍にする操作- この操作により、各偶数が2倍になります。
- 終端操作(結果の出力):
.forEach(System.out::println)
forEach()
は終端操作で、ストリームの各要素に対して処理を行います。System.out::println
はメソッド参照という特殊なラムダ式の形です。- これは
n -> System.out.println(n)
と同等です - 各要素を標準出力に印字します
出力結果:
4
8
12
16
20
- 元の配列の偶数(2, 4, 6, 8, 10)が2倍になった結果が出力されます。
このように、Stream APIとラムダ式を使用することで、複雑な処理を簡潔かつ読みやすく書くことができます。これらの機能は、大量のデータを効率的に処理する際に特に有用です。
まとめ
- 配列の宣言と初期化には、new演算子を使用する方法と初期化子リストを使用する方法がある
- 配列の主要な特徴として、固定サイズ、インデックスベースのアクセス、型安全性がある
- 配列の長さはlengthプロパティで取得でき、要素へのアクセスはインデックスを使用する
- 多次元配列を使用することで、より複雑なデータ構造を表現できる
- Java 8以降では、Stream APIとラムダ式を使用することで、配列操作をより簡潔に記述できる
Javaの配列は、プログラミングの基本的なデータ構造の一つであり、効率的なデータ管理と操作を可能にします。本記事で学んだ基本的な配列の扱い方から、Stream APIを用いた高度な操作まで、様々なシーンで活用することができます。配列の特性を理解し、適切に使用することで、より効率的で読みやすいコードを書くことができます。
コメント