配列 Array
配列の概要
配列は、同じ型のデータのセットを保持するために使用されます。配列内の各データは要素と呼ばれ、各要素には対応するインデックスがあります。
Java 配列には以下の特徴があります。
- 配列は同じデータ型の要素のみを保持できます。
- 配列は固定長で作成され、直接変更できません。
- 配列はインデックスによって要素に素早くアクセスできます。
- 配列の途中で要素を挿入または削除するときは、通常、他の要素を移動する必要があります。
配列のサイズを拡大する必要がある場合、通常はより大きな新しい配列を作成し、元の配列の要素をコピーします。
1 次元の配列
変数の定義
データ型の後に角括弧を書くことをお勧めします。
int[] numbers;
double[] prices;
String[] names;
変数名の後に角括弧を付けることもできますが、推奨されません。
int numbers[];
配列は参照型に属します。
グループの作成です
1 次元配列の静的初期化
静的初期化は、配列変数を宣言するときに要素の値を直接指定し、配列の長さは要素の数によって決まります。
int[] numbers = {2, 5, 7, 8};
完全な形式で書くこともできます:
int[] numbers = new int[] {2, 5, 7, 8};
省略されたnew int[]の短縮形は、変数宣言時にのみ使用できます。
1 次元配列の動的初期化
動的初期化は配列の長さを指定し、システムが各要素のデフォルト値を設定します。
int[] numbers = new int[3];
異なるタイプの配列要素のデフォルト値は次のとおりです。
| 要素タイプ | 既定値 |
|---|---|
| integer 型 | 0 |
| 浮動小数点型 | 0.0 0です。 |
char | \u0000 |
| boolean` | false |
| 参照型の種類 | null |
メモリの配列モデル
プリミティブ型変数はプリミティブ型の値を直接保持し、参照型変数はオブジェクト参照を保持します。参照変数の具体的なメモリサイズはJVMの実装と実行モードによって決まり、単純にバイト数に固定されるとは考えられません。

nullは、参照変数が現在オブジェクトを指しておらず、参照型変数にのみ割り当てられることを意味します。
String text = null;
int[] numbers = null;
配列オブジェクトは作成されるとヒープメモリに配置され、配列変数はその配列オブジェクトへの参照を保持します。
String[] names = new String[] {"ab", "cd", "e"};

配列要素のアクセス
配列インデックスは0から始まり、最大インデックスはarray.length - 1です。
int[] numbers = {3, 5, 6, 4, 25, 7, 3, 8, 9};
System.out.println(numbers[0]);
numbers[0] = 30;
System.out.println(numbers[numbers.length - 1]);
存在しないインデックスにアクセスすると、ArrayIndexOutOfBoundsExceptionがスローされます。

配列を横断する
通常 forループの使用
int[] numbers = {3, 5, 6, 4, 25, 7, 3, 8, 9};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
通常のforサイクルはインデックスと要素値の両方を取得できます。
Enhanced for Loopの使用
for (int number : numbers) {
System.out.println(number);
}
拡張forループは要素値のみを読み取るシーンに適しており、現在のインデックスを直接取得できません。
最大値、最小値、合計値
配列が空の場合、最初の要素を直接読み取ることはできないので、以下の記述では少なくとも1つの要素を含む必要があります。
int[] numbers = {3, 5, 6, 4, 25, 7, 3, 8, 9};
int max = numbers[0];
int min = numbers[0];
int sum = 0;
for (int number : numbers) {
if (number > max) {
max = number;
}
if (number < min) {
min = number;
}
sum += number;
}要素を探す
Scanner scanner = new Scanner(System.in);
int target = scanner.nextInt();
int[] numbers = {3, 5, 6, 4, 25, 7, 3, 8, 9};
boolean found = false;
for (int number : numbers) {
if (number == target) {
found = true;
break;
}
}
System.out.println(found ? "有" : "没有");配列のコピー
次のコードは、元の配列要素を逆の順序で新しい配列にコピーします。
int[] source = {3, 5, 6, 4, 25, 7, 3, 8, 9};
int[] target = new int[source.length];
for (int i = 0; i < source.length; i++) {
target[i] = source[source.length - 1 - i];
}
ソート·ソート
ソートを選択
int[] numbers = {3, 5, 6, 4, 25, 7, 2, 8, 9, 11};
for (int i = 0; i < numbers.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[j] < numbers[minIndex]) {
minIndex = j;
}
}
if (minIndex != i) {
int temp = numbers[i];
numbers[i] = numbers[minIndex];
numbers[minIndex] = temp;
}
}バブリングソート
int[] numbers = {3, 5, 6, 4, 25, 7, 2, 8, 9, 11};
for (int i = 0; i < numbers.length - 1; i++) {
boolean swapped = false;
for (int j = 0; j < numbers.length - 1 - i; j++) {
if (numbers[j] > numbers[j + 1]) {
int temp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = temp;
swapped = true;
}
}
if (!swapped) {
break;
}
}実際の開発では通常Arrays.sort()をそのまま使用する.
乱数の数
Randomクラス
nextInt(bound)は0からbound - 1までの整数を生成する.
Random random = new Random();
int number1 = random.nextInt(10); // 0~9
int number2 = random.nextInt(6) + 5; // 5~10
以下のコードはFisher-Yatesの考え方を使って配列をシャッフルし、毎回任意の位置と交換するよりも均一にします。
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = numbers.length - 1; i > 0; i--) {
int index = random.nextInt(i + 1);
int temp = numbers[i];
numbers[i] = numbers[index];
numbers[index] = temp;
}
Math.random()
Math.random()は、0.0以上で1.0未満のdouble値を返します。
int number1 = (int) (Math.random() * 10); // 0~9
int number2 = (int) (Math.random() * 6) + 5; // 5~10
int number3 = (int) (Math.random() * 11) - 5; // -5~5
2 次元配列
2 次元配列の定義
2 次元配列の要素は1 次元配列のままであるため、Javaの2 次元配列は本質的に“配列の配列”です。
int[][] matrix;
以下の形式で書くこともできますが、推奨されません。
int matrix[][];
2 次元グループの作成
二次元配列の静的初期化
静的初期化は、配列を作成しながら配列要素に値を代入することです。
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8}
};
完全な形式で書くこともできます:
int[][] matrix = new int[][] {
{1, 2},
{3, 4, 5}
};
第 1の配列のの长さは3であり、3つの配列の长さはそれぞれ3、3、2である。
2 次元配列の動的初期化
外部グループのみを作成
int[][] matrix = new int[3][];
このコードでは、長さ3の外側配列のみを作成します。この時点で、matrix[0]、matrix[1]、matrix[2]はすべてnullであり、内部配列はまだ作成されていないため、配列オブジェクトは1つだけです。

異なる長さの内部配列を別々に作成することができ、不規則な2 次元配列を形成することができます。
matrix[0] = new int[2];
matrix[1] = new int[4];
matrix[2] = new int[1];
外側配列と内側配列の両方を作成する
int[][] matrix = new int[3][2];
このコードでは、長さ3の外側配列と長さ2の3つの内側配列を作成し、合計 4つの配列オブジェクトを作成します。

外側の配列を作成し、次に3つの内側の配列を作成するのと同じです。
int[][] matrix = new int[3][];
for (int i = 0; i < matrix.length; i++) {
matrix[i] = new int[2];
}
2 次元配列要素のアクセス
2つのインデックスを使用して2 次元配列要素にアクセスします。最初のインデックスは内側の配列を、2 番目のインデックスは内側の配列の要素を検索します。
int[][] matrix = {
{1, 2},
{3, 4, 5}
};
System.out.println(matrix[1][2]); // 5
要素にアクセスする前に、内部配列がnullでなく、両方のインデックスが境界を越えていないことを確認してください。
2 次元グループの通過
int[][] matrix = {
{1, 2},
{3, 4, 5}
};
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.println(matrix[i][j]);
}
}Enhanced forサイクルも使用できます。
for (int[] row : matrix) {
for (int value : row) {
System.out.println(value);
}
}
2 次元グループの検索
int[][] matrix = {
{1, 2},
{3, 4, 5}
};
int target = 4;
boolean found = false;
outer:
for (int[] row : matrix) {
for (int value : row) {
if (value == target) {
found = true;
break outer;
}
}
}
System.out.println(found ? "有" : "没有");2 次元配列の深いコピー
外側の配列のみをコピーすると、新旧の2 次元配列が内側の配列を共有するようになります。独立したコピーを実装するには、各内部配列のコピーを継続する必要があります。
int[][] source = {
{1, 2},
{3, 4, 5}
};
int[][] target = new int[source.length][];
for (int i = 0; i < source.length; i++) {
target[i] = Arrays.copyOf(source[i], source[i].length);
}不規則な二次元配列
Javaは内部配列の長さを異なる。
int[][] matrix = new int[3][];
matrix[0] = new int[] {1, 2};
matrix[1] = new int[] {3, 4, 5};
matrix[2] = new int[] {6};
不規則な2 次元配列をトラバースする場合は、各行が同じ長さであると仮定しないで、現在の内部配列のlengthを使用してください。
Arraysツールクラス
配列をコピー
int[] source = {4, 3, 2, 6, 7, 9, 1, 10, 11};
int[] copy = Arrays.copyOf(source, source.length);
Arrays.copyOfRange()の終了インデックスは、複製範囲に含まれません。
int[] part = Arrays.copyOfRange(source, 0, 5);
配列を並べ替える
int[] numbers = {4, 3, 2, 6, 7, 9, 1, 10, 11};
Arrays.sort(numbers);
2つの検索
Arrays.binarySearch()では、配列が同じルールでソートされていることを要求します。要素が見つかった場合は非負のインデックス、見つからなかった場合は負のインデックスを返します。
int[] numbers = {4, 3, 2, 6, 7, 9, 1, 10, 11};
Arrays.sort(numbers);
if (Arrays.binarySearch(numbers, 8) >= 0) {
System.out.println("有");
} else {
System.out.println("没有");
}
System.arraycopy()
System.arraycopy()は、ソース配列の指定範囲をターゲット配列の指定位置にコピーすることができる。
int[] source = {1, 2, 3, 4, 5, 6, 7};
int[] target = new int[10];
System.arraycopy(source, 2, target, 4, 2);
System.out.println(Arrays.toString(target));
上记のコードでは、ソース配列インデックス2、3の位置の要素をターゲット配列インデックス4、5の位置にコピーします。
気に入ったならばコメントを残してくださいね~