Java の配列 (詳細なケース)

目次

配列

1.コンセプト

2. 配列の作成と構成

2.1 配列の作成

2.2 アレイの構成

3. 配列アクセス

3.1 直接アクセス

3.2 添え字の範囲外問題

3.3 配列の走査

3.4 配列のデフォルト値

3.5 配列を作成する一般的な方法

4. 配列の拡張

4.1 容量を拡張する手順

4.2 System.arrayCopy は配列をコピーします

4.3 Arrays.copyOf を使用して配列をコピーする

5. 参照渡しと値渡し

6. 可変長パラメータ

7. 配列のソート

7.1 バブルソート

7.2 選択の並べ替え

7.3 挿入ソート

7.4 JDKのソート

8. 2次元配列


配列

1.コンセプト

同じ型の変数を複数格納する必要がある場合、複数の変数を定義するのは面倒であり、統一的に操作するには不便です。

現時点では配列を使用する必要があります。

配列は、同じタイプのデータを格納するためのメモリ内の連続スペースを定義します。

  • 連続した空間

  • 長さは作成時に固定されます

  • 同じ種類のデータを保存する

注:配列は参照データ型です。

2. 配列の作成と構成

2.1 配列の作成

配列を作成する場合は、型と長さを指定します。

public class Test1 {
    public static void main(String[] args) {
        // 类型是int数组,表示在该数组存储的数据是int类型
        // 5表示数组的长度,意味着能存储5个int类型的数据
        int [] arr1 = new int[5];
        
        // 存储7个double类型的数据的一块连续空间
        double [] arr2 = new double[7];
        
        // 存储8个String类型的数据的一块连续空间
        String [] arr3 = new String[8];
    }
}

2.2 アレイの構成

配列は連続した空間であり、配列名は配列の先頭アドレスに相当し、データ要素にアクセスする場合は配列名+添え字の形式でアクセスします。例: arr[0] は配列名が arr であることを意味し、0 は最初の要素を表す添字を意味します。

配列の要素が 5 個の場合、添え字は 0 ~ 4、

3. 配列アクセス

3.1 直接アクセス

public class Test2 {
    // 赋值和取值
    public static void main(String[] args) {
        // 类型是int数组,表示在该数组存储的数据是int类型
        // 5表示数组的长度,意味着能存储5个int类型的数据
        int [] arr1 = new int[5];
        
        // 赋值
        arr1[0] = 20;
        arr1[1] = 30;
        arr1[2] = 40;
        arr1[3] = 50;
        arr1[4] = 60;
        
        // 取值
        System.out.println(arr1[0]);
        System.out.println(arr1[1]);
        System.out.println(arr1[2]);
        System.out.println(arr1[3]);
        System.out.println(arr1[4]);
//      System.out.println(arr1[5]); // 下标越界
    }
}

3.2 添え字の範囲外問題

上記のコードのように、アクセスした添え字が範囲外の場合に arr1[5] を使用すると例外が発生します。

java.lang.ArrayIndexOutOfBoundsException

3.3 配列の走査

ループを使用して配列のすべての要素にアクセスします。

注:配列では、長さを表すために長さを使用します。

public class Test2 {
    // 赋值和取值
    public static void main(String[] args) {
        // 类型是int数组,表示在该数组存储的数据是int类型
        // 5表示数组的长度,意味着能存储5个int类型的数据
        int [] arr1 = new int[5];
        
        // 赋值
        arr1[0] = 20;
        arr1[1] = 30;
        arr1[2] = 40;
        arr1[3] = 50;
        arr1[4] = 60;
        
        // 循环遍历
        for (int i = 0; i < arr1.length; i++) {
            System.out.println(arr1[i]);
        }
    }
}

3.4 配列のデフォルト値

配列の作成時に要素に値が割り当てられていない場合は、デフォルト値が使用されます。デフォルト値は配列の種類によって異なります。

整数型、デフォルト値は 0

10 進数タイプ、デフォルト値は 0.0

ブール型、デフォルト値は false

文字タイプ、デフォルト値は 0

その他の型、デフォルト値は null

null は Java のキーワードであり、スペースが割り当てられず、null 値であることを意味します。

public class Test3 {
    // 数组的默认值
    public static void main(String[] args) {
        // 局部变量需要先赋值才能取值
//      int n;
//      System.out.println(n); // 报错
        
        int [] arr = new int[5];
        
        // 数组元素没有赋值时,是使用的默认值
        // 
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        } 
    }
}

3.5 配列を作成する一般的な方法

public class Test4 {
    // 数组的创建方式
    public static void main(String[] args) {
        // 1、先声明,后分配空间
        int arr1 []; // int [] arr2;
        arr1 = new int[3];
        
        // 2、声明同时分配空间
        int [] arr2 = new int[3];
        
        // 3、声明并赋值,注意:会自动推断数组的长度,不允许写入长度
        int [] arr3 = new int[] {20, 30, 40};
        
        // 4、声明并赋值,简化版
        int [] arr4 = {20, 30, 40};
        
        // 如果要使用先声明,后分配空间的同时赋值
        int [] arr5;
        arr5 = new int[] {20, 30, 40, 50};
        
        // 不能简写
        int [] arr6;
//      arr6 = {20, 30, 40, 50}; // 报错
    }
}

ケース 1:

public class Test5 {
    // 给定一个数组长度为10,赋值100以内随机数,打印所有的数字以及其平均数
    public static void main(String[] args) {
        // 定义数组,长度为10
        int [] arr = new int[10];
        
        // 定义和值
        int sum = 0;
        // 赋值并求和
        Random random = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(100);
            sum += arr[i]; // 求和
        }
        
        // 打印输出
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        // 打印平均数
        double avg = (double)sum / arr.length;
        System.out.println("平均数为:" + avg);
    }
}

ケース 2:

public class Test6 {
    // 输入一个数字,判断数组中是否包含该数字,如果包含,输出下标,不包含则输出-1
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        
        // 给定一个数组
        int [] arr = {12, 34, 745, 88, 98};
        
        // 接收一个数字
        System.out.println("请输入一个数字:");
        int num = input.nextInt();
        
        int index = -1; // 定义下标
        for (int i = 0; i < arr.length; i++) {
            if(num == arr[i]) {
                index = i; // 将下标记住
                break;
            }
        }
        
        System.out.println("下标为:" + index);
    }
}

ケース 3: 配列要素の順序を逆にします。

4. 配列の拡張

4.1 容量を拡張する手順

配列の長さは固定されているため、配列内の要素がいっぱいの場合は、配列に要素を追加して容量を拡張する必要があります。

拡張の手順は次のとおりです。

  • 1. 十分な長さの新しい配列を作成します。

  • 2. 元の配列の要素を新しい配列に入れ、新しく追加した要素を新しい配列に順番に入れます。

public class Test9 {
    // 数组扩容
    public static void main(String[] args) {
        int [] arr = {12, 34, 745, 88, 98};
​
        // 创建一个新的数组
        int [] arr1 = new int[arr.length + 1];
        
        // 将原数组中的元素放入到新数组中
        for (int i = 0; i < arr.length; i++) {
            arr1[i] = arr[i];
        }
        
        // 添加新元素
        arr1[arr.length] = 50;
        
        // 输出新数组
        System.out.println(Arrays.toString(arr1));
    }
}
public class Test10 {
    // 向数组中添加元素
    public static void main(String[] args) {
        int [] arr = {12, 34, 745, 88, 98};
​
        arr = add(arr, 35);
        
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
​
    public static int[] add(int[] arr, int num) {
        // 创建一个新数组
        int [] newArray = new int[arr.length + 1];
        // 将原数组中的内容复制到新数组中
        for (int i = 0; i < arr.length; i++) {
            newArray[i] = arr[i];
        }
        // 将要添加的元素添加到新数组的最后
        newArray[arr.length] = num;
        return newArray;
    }
}

4.2 System.arrayCopy は配列をコピーします

システム独自のメソッドを使用して、配列の内容をコピーできます。

ケース: 配列の結合

public class Test12 {
    // 数组合并
    public static void main(String[] args) {
        int [] arr1 = {1, 2, 3, 4, 5}; // 数组1
        int [] arr2 = {6, 7, 8, 9}; // 数组2
​
        // 创建新数组长度为数组1和数组2长度之和
        int [] newArray = new int[arr1.length + arr2.length];
        
//      // 将数组1的元素复制到新数组中
//      for (int i = 0; i < arr1.length; i++) {
//          newArray[i] = arr1[i];
//      }
//      
//      // 将数组2的元素复制到新数组中
//      for (int i = 0; i < arr2.length; i++) {
//          newArray[arr1.length + i] = arr2[i];
//      }
        
        System.arraycopy(arr1, 0, newArray, 0, arr1.length);
        System.arraycopy(arr2, 0, newArray, arr1.length, arr2.length);
        
        System.out.println(Arrays.toString(newArray));
    }
}

4.3 Arrays.copyOf を使用して配列をコピーする

copyOf メソッドは、元の配列のコピーに基づいて新しい配列を作成し、それを返します。

public class Test13 {
    // 使用copyOf数组合并
    public static void main(String[] args) {
        int [] arr1 = {1, 2, 3, 4, 5}; // 数组1
        int [] arr2 = {6, 7, 8, 9}; // 数组2
​
        int [] newArray = join(arr1, arr2);
        
        System.out.println(Arrays.toString(newArray));
    }
​
    public static int[] join(int [] arr1, int [] arr2) {
        // 完全复制arr1并创建一个指定长度的新数组
        int [] newArray = Arrays.copyOf(arr1, arr1.length + arr2.length);
        System.arraycopy(arr2, 0, newArray, arr1.length, arr2.length);
        return newArray;
    }
}

Arrays クラスは、配列を操作するためにシステムによって提供される複数のメソッドをカプセル化したものです。

5. 参照渡しと値渡し

基本的なデータ型は値によって渡されます。

参照データ型は参照によって渡されます。

public class Test14 {
    // 引用传递
    public static void main(String[] args) {
        // 基本数据类型值传递
        int n = 5;
        int m = n;
        m = 8;
        System.out.println(n);
        
        // 引用数据类型引用(地址)传递
        int [] arr1 = {1, 2, 3, 4, 5};
        int [] arr2 = arr1;
        arr1[2] = 10;
        System.out.println(arr2[2]);
        
        // 在方法参数时也是值传递
        int i = 3;
        m1(i);
        System.out.println(i);
        
        // 方法参数传递时,如果是数组,是引用传递
        int [] arr3 = {1, 2, 3, 4, 5};
        m2(arr3);
        System.out.println(arr3[1]);
    }
​
    public static void m2(int [] arr) {
        arr[1] = 10;
    }
    
    public static void m1(int m) {
        m = 8;
    }
}

配列をパラメータとしてメソッドに渡します。メソッドが配列要素のみを操作する場合、外部配列も同じアドレスであるため変更されます。ただし、メソッド内で新しい配列が作成された場合、外部配列は変更を要求します。新しい配列 (戻り値として返される配列) にアクセスします。

public class Test15 {
    // 演示方法中创建数组
    public static void main(String[] args) {
        int [] arr = {1, 2, 3, 4, 5};
        arr = m1(arr);
        System.out.println(Arrays.toString(arr));
    }
​
    public static int[] m1(int [] arr1) {
        arr1 = new int[6];
        for (int i = 0; i < arr1.length; i++) {
            arr1[i] = i + 1;
        }
        return arr1;
    }
}

6. 可変長パラメータ

配列を使用する場合と同様に、配列をメソッドのパラメーターとして使用する場合の呼び出しプロセスを簡素化します。

構文: 配列を表すには、メソッド パラメーターで type... を使用します。

例えば:

public class Test1 {
    public static void main(String[] args) {
        printArr();
        printArr(1);
        printArr(1, 3, 5);
    }
    
​
    public static void printArr(int... arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

知らせ:

  • これはメソッドのパラメーターでのみ使用でき、変数の定義には使用できません。

  • メソッドパラメータリストの最後のパラメータとしてのみ記述できます。

  • パラメーター リストには可変個引数パラメーターを 1 つだけ含めることができます。

7. 配列のソート

並べ替えとは、配列内の要素が順序付けられたシーケンスになるように、配列内の要素を指定された順序で配置することを指します。

多くの検索アルゴリズムは順序付けられた順序で実行する必要があるため、並べ替えが必要であり、並べ替え自体がアルゴリズムです。

1. バブルソーティング

2. 並べ替えを選択します

3. 挿入ソート

7.1 バブルソート

public class Test2 {
    // 冒泡排序
    public static void main(String[] args) {
        int [] arr = {90, 12, 35, 80, 54, 7, 4, 15};
        // 需要的轮次,arr.length - 1
        // 比较时使用的下标:i,i + 1
        // 比较的次数,第0轮arr.length - 1次,
        //      第1轮 arr.length - 2,第2轮 arr.length - 3,第n轮arr.length - n - 1
        // 比较过程中,如果需要由小到大排序,那么下标i比i+1的数字要大,则进行交换
        // 12, 35, 80, 54, 7, 4, 15,            90
        // 12, 35, 54, 7, 4, 15,            80  90
        // 12, 35, 7, 4, 15,            54  80  90
    
        
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if(arr[j] > arr[j + 1]) {
                    arr[j] = arr[j] ^ arr[j + 1];
                    arr[j + 1] = arr[j] ^ arr[j + 1];
                    arr[j] = arr[j] ^ arr[j + 1];
                }
            }
        }
        
        System.out.println(Arrays.toString(arr));
    }
}

7.2 選択の並べ替え

public class Test3 {
    // 选择排序
    public static void main(String[] args) {
        int [] arr = {90, 12, 35, 80, 54, 7, 4, 15};
        // 需要的轮次,arr.length - 1
        // 比较时使用的下标:i,j, min
        // 交换是交换的i和min
        // 比较的次数j
        // j的值从1开始,每轮都加1,j的值应该等于i+1
        // 4, 12, 35, 80, 54, 7, 90, 15
        // 4, 7, 35, 80, 54, 12, 90, 15
        // 4, 7, 12, 80, 54, 35, 90, 15
        // 4, 7, 12, 15, 54, 35, 90, 80
        
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i; // 记住当前位置
            // 循环后面的元素,用比较的方式寻找最小元素的下标
            for (int j = i + 1; j < arr.length; j++) {
                if(arr[j] < arr[min]) {
                    min = j;
                }
            }
            
            // 如果最小元素下标不是当前轮次对应下标的元素,则进行交换
            if(min != i) {
                int temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
            }
        }
        
        System.out.println(Arrays.toString(arr));
    }
}

7.3 挿入ソート

public class Test4 {
    // 插入排序
    public static void main(String[] args) {
        int [] arr = {90, 12, 35, 80, 54, 7, 4, 15};
        // 需要的轮次,arr.length - 1
        // 比较时使用的下标:i,j, min
        // 12, 90, 35, 80, 54, 7, 4, 15
        // 12, 35, 90, 80, 54, 7, 4, 15
        // 12, 35, 80, 90, 54, 7, 4, 15
        // 12, 35, 54, 80, 90, 7, 4, 15
        //                  i  j
        
        for (int i = 0; i < arr.length - 1; i++) {
            int j = i + 1; // 需要比较的下标
            int num = arr[j]; // 记住当前元素
            for (; j > 0; j--) { // 向前循环比较
                if(num < arr[j-1]) { // 当前元素如果比前面的元素小,前面的元素需要向后移动
                    arr[j] = arr[j-1]; // 向后移动
                }else { // 当不需要移动时,当前位置即是需要比较的元素所占据的位置,停止循环,记住位置
                    break;
                }
            }
            arr[j] = num; // 将该位置插入当前比较的元素,如果循环完毕,说明该元素应该放到最前面
        }
        
        System.out.println(Arrays.toString(arr));
    }
}

7.4 JDKのソート

public class Test5 {
    // JDK排序
    public static void main(String[] args) {
        int [] arr = {90, 12, 35, 80, 54, 7, 4, 15};
        
        // 排序
        Arrays.sort(arr);
        
        System.out.println(Arrays.toString(arr));
    }
}

8. 2次元配列

public class Test6 {
    // 多维数组
    public static void main(String[] args) {
        // 直接定义并赋值
        int [][] arr = {
                {1, 2},
                {3, 4, 5, 6},
                {7, 8, 9}
        };
        
        System.out.println(arr[0][1]);
        
        // 先分配行空间
        int [][] arr1 = new int[5][];
        // 循环行
        for (int i = 0; i < arr1.length; i++) {
            arr1[i] = new int[5]; // 分配列空间
            for (int j = 0; j < arr1[i].length; j++) {
                arr1[i][j] = (i) * 5 + (j+1); 
            }
        }
        
//      for (int i = 0; i < arr1.length; i++) { // 行
//          for (int j = 0; j < arr1[i].length; j++) { // 列
//              System.out.println(arr1[i][j]);
//          }
//      }
        
        System.out.println(Arrays.deepToString(arr1));
        
        int [][] arr2 = new int[5][5];
        
        int [] arr3 [];
    }
}

ケース: ヤン・フイ・トライアングル

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

1 5 10 10 5 1

public class Test7 {
    // 杨辉三角
    public static void main(String[] args) {
        int row = 10;
        int [][] arr = new int[row][];
        
        // 赋值
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[i+1];
            for (int j = 0; j < arr[i].length; j++) {
                if(j == 0 || j == arr[i].length - 1) {
                    arr[i][j] = 1;
                }else {
                    arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
                }
            }
        }
        
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

おすすめ

転載: blog.csdn.net/asdf12388999/article/details/127117117