当前位置: 首页 > article >正文

深入理解 Java 基本语法之数组

目录

一、数组基础概念

二、数组的声明

1. 基本数据类型数组声明:

2. 引用数据类型数组声明:

三、数组的创建

四、数组的初始化

五、数组的使用

​编辑1. 获取长度以及访问元素:

2. 数组作为方法的参数:

3. 数组作为方法的返回值:

六、多维数组

1. 二维数组的声明和初始化

2. 调用数组的指定位置的元素

3. 获取数组的长度

4. 遍历二维数组

5. 二维数组元素的默认初始化值

七、Arrays 类

1. 判断两个数组是否相等

2. 输出数组信息

3. 将指定值填充到数组之中

4. 对数组进行排序

5. 对排序后的数组进行二分法检索指定的值

八、数组的常见应用场景        ​编辑


一、数组基础概念

数组是同一种类型数据的集合,是一种容器,能给存储进来的元素自动进行编号,编号从 0 开始。数组有以下特点:

  1. 长度确定且不可变。一旦数组被初始化,其长度就不能再改变。例如在 Java 中,定义一个整型数组int[] arr = new int[5];,这个数组的长度就是 5,不能在后续的代码中增加或减少这个数组的长度。
  2. 元素必须是相同类型。Java 中的数组要求数组中的元素类型统一,不能存储不同类型的元素。例如不能在一个整型数组中存储字符串类型的数据。
  3. 数组变量属引用类型,数组本身也是对象,在堆中分配空间。Java 语言中的数组是一种引用类型,不属于基本数据类型。数组的父类是 Object。数组实际上是一个容器,可以同时容纳多个元素。数组因为是引用类型,所以数组对象是在堆内存当中。数组当中如果存储的是 “Java 对象” 的话,实际上存储的是对象的 “引用(内存地址)”。

二、数组的声明

数组在 Java 中有多种声明方式,主要分为基本数据类型数组声明和引用数据类型数组声明。

1. 基本数据类型数组声明:

        基本数据类型数组可以使用int[] i或int i[]的方式进行声明。例如,声明一个整型数组可以写为int[] numbers或int numbers[]。Java 中更推荐使用int[] numbers这种方式,因为它具有更好的可读性。

2. 引用数据类型数组声明:

        引用数据类型数组可以使用Car[] c或Car c[]的方式进行声明,在 Java 中推荐用Car[] c。比如,如果有一个自定义的类Person,声明一个Person类型的数组可以写为Person[] people。引用数据类型的数组在声明后也需要进行初始化才能使用。初始化的方式可以是静态初始化或动态初始化。例如,静态初始化可以这样写:Person[] people = new Person[]{new Person("张三", 1), new Person("李四", 2)};动态初始化可以这样写:Person[] people = new Person[3],然后再通过给每个元素赋值的方式进行初始化,如people[0] = new Person("王五", 3)。

三、数组的创建

数组在 Java 中有多种创建方式,下面分别介绍基本数据类型数组和引用数据类型数组的创建方法。

  1. 创建基本数据类型数组:可以使用int[] i = new int[2];的方式创建一个整型基本数据类型数组。这种方式在创建时指定了数组的长度为 2,创建后数组中的元素会被初始化为对应类型的默认值,对于整型来说,默认值为 0。
  2. 创建引用数据类型数组:以Car[] c = new Car[100];为例,可以创建一个引用数据类型数组。假设Car是一个自定义的类,这种方式创建了一个长度为 100 的Car类型数组。创建后,数组中的每个元素初始值为 null,因为引用类型的默认值为 null。
  3. 数组创建后有初始值,数字类型为 0,布尔类型为 false,引用类型为 null。例如,创建一个byte类型的数组,其元素默认初始值是 0;创建一个float类型的数组,其元素默认初始值是 0.0f;创建一个boolean类型的数组,其元素默认初始值是 false;如果创建一个自定义的引用类型数组,如Person[] people = new Person[3],那么创建后数组中的每个元素初始值为 null。

四、数组的初始化

数组的初始化方式主要有以下几种:

  1. 初始化、创建、和声明分开:
    • 首先进行声明:int[] i;
    • 然后创建数组并指定长度:i = new int[2];
    • 最后为数组元素赋值:i[0] = 0;,i[1] = 1;。
  1. 初始化、创建、和声明在同一时间:

 

  • 可以使用int[] i = {0,1};的方式,直接在声明的同时为数组元素分配空间并赋值。

 

  • 也可以使用int[] i = new int[]{1,2,3,4,5};的方式,先使用new关键字创建数组,同时为数组中的元素赋值,这里不需要指定数组的长度,数组长度由其后的初始化操作确定。

        数组的初始化方式还包括静态初始化、动态初始化和默认初始化。静态初始化是在定义数组的同时为数组元素分配空间并赋值,由系统决定数组的长度,例如int[] a = {1,2,3}或Man[] mans = {new Man(1, 1), new Man(2, 2)}。动态初始化是在初始化时由程序员指定数组的长度,由系统初始化每个数组元素的默认值,例如int[] a1 = new int[2],然后再给数组元素赋值。默认初始化是对于引用类型的数组,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化,例如int a2[] = new int[2],其默认值为0,0;boolean[] b = new boolean[2],其默认值为false,false;String[] s = new String[2],其默认值为null,null。

        注意:不要同时使用静态初始化和动态初始化,一旦数组完成初始化,数组在内存中所占的空间将被固定下来,所以数组的长度将不可改变。

五、数组的使用

1. 获取长度以及访问元素:

        在 Java 中,获取数组长度非常简单,可以使用arr.length表示获取数组长度。例如:

int[] numbers = {1, 2, 3, 4, 5};
int length = numbers.length;
System.out.println("数组的长度是: " + length);

访问数组元素可以通过System.out.println(arr[0]);的方式。还可以通过循环语句打印全部元素,如:

for(int i = 0;i < arr.length;i++){
    System.out.println(arr[i]);
}

        此外,还有 for-each 遍历数组语句:for(int i : arr){System.out.println(i);},此方法不可以改变数组的值,只是数组的复制值。

2. 数组作为方法的参数:

        可以将数组作为方法的参数来打印数组内容。理解引用类型参数传内置类型时,形参的结果不会影响实参值;参数传数组类型时,在函数内部修改数组内容,函数外部也发生改变。例如:        

public static void main(String[] args) {
    int[] arr = {1, 3, 5};
    System.out.println(arr[0]);
    change(arr);
    System.out.println(arr[0]);
}
public static void change(int[] arr) {
    arr[0] = 200;
}

3. 数组作为方法的返回值:

数组也可以作为方法的返回值。比如:

 
public class Demo02ArrayReturn {
    public static void main(String[] args) {
        int[] result = calculate(10, 20, 30);
        System.out.println("main方法接收到的返回值数组是:");
        System.out.println(result); // 地址值
        System.out.println("总和:" + result[0]);
        System.out.println("平均数:" + result[1]);
    }
    public static int[] calculate(int a, int b, int c) {
        int sum = a + b + c; // 总和
        int avg = sum / 3; // 平均数
        int[] array = {sum, avg};
        System.out.println("calculate方法内部数组是:");
        System.out.println(array); // 地址值
        return array;
    }
}

六、多维数组

1. 二维数组的声明和初始化

  • Java 中二维数组可以有多种声明和初始化方式,例如:
    • int[][] arr1=new int[][]{{1,2,3},{4,5,6}};:这是一种静态初始化的方式,直接在创建数组的同时为其赋值。
    • String[][] arr2=new String[3][2];:动态初始化,指定了二维数组的外层长度为 3,内层长度为 2,但未为元素赋值。
    • String[][] arr3=new String[3][];:动态初始化,只指定了外层长度为 3,内层长度未确定。
    • int[] arr4[]=new int[][]{{1,2,3},{4,5,6}};:另一种声明方式,与第一种类似,也是静态初始化。
    • int[] arr5[]={{1,2,3},{4,5,6}};(类型推断):简洁的初始化方式,省略了new关键字,但效果与第一种相同。

2. 调用数组的指定位置的元素

  • 二维数组的元素可以通过指定行和列的索引来访问。例如,对于二维数组arr,内层元素可以通过arr[行索引][列索引]来访问,如arr[3][2];外层元素可以通过只指定行索引来访问,如arr[3]。

3. 获取数组的长度

  • 在二维数组中,可以使用arr.length来获取外层元素的数量,即数组的行数。而要获取某一行(外层元素)的长度(列数),可以使用arr[行索引].length。例如,如果有一个二维数组int[][] arr = {{1,2,3},{4,5,6}};,那么arr.length的值为 2,arr[0].length的值为 3。

4. 遍历二维数组

  • 二维数组可以使用嵌套的for循环来遍历。外层for循环遍历外层元素,控制行数;内层for循环遍历内层元素,控制列数。例如:
 
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr[i].length; j++) {
        System.out.print(arr[i][j] + " ");
    }
    System.out.println();
}

这段代码会依次输出二维数组中的每一个元素,每输出完一行元素后换行。

5. 二维数组元素的默认初始化值

  • 对于初始化方式int[][] arr = new int[4][3];,外层元素的初始化值为地址值,内层元素的初始化值与一维数组初始化情况相同。例如,对于整型二维数组,内层元素的初始值为 0。
  • 对于初始化方式int[][] arr=new int[4][];,外层元素的初始化值为null,内层元素的初始化值不能调用,否则会报错。例如:
int[][] arr = new int[4][];
System.out.println(arr[0]); // null
// System.out.println(arr[0][0]); // 会报错,空指针异常

七、Arrays 类

        Java 中的java.util.Arrays类是操作数组的工具类,包含了用来操作数组的各种方法,如判断两个数组是否相等、输出数组信息、将指定值填充到数组之中、对数组进行排序、对排序后的数组进行二分法检索指定的值。

1. 判断两个数组是否相等

        可以使用Arrays.equals(数组1,数组2)方法来判断两个数组是否相等。数组类型必须相等,该方法的返回值为boolean类型。例如:

int[] arr1 = new int[]{1,2,3,4,6};
int[] arr2 = new int[]{1,2,3,4,5};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);

2. 输出数组信息

        使用Arrays.toString(数组名)方法可以输出数组信息。例如:

int[] arr2 = new int[]{1,2,3,4,5};
System.out.println(Arrays.toString(arr2));

3. 将指定值填充到数组之中

        Arrays.fill(数组名,填充值)方法可以将指定值填充到数组之中。填充值数据类型应与数组数据类型相同,该方法会把要填充的数组数据全部改为指定值。例如:

int[] arr2 = new int[]{1,2,3,4,5};
Arrays.fill(arr2,9);
System.out.println(Arrays.toString(arr2));

4. 对数组进行排序

        使用Arrays.sort(数组名)方法可以对数组进行排序。例如:

int[] arr2 = new int[]{5,4,1,2,3};
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));

5. 对排序后的数组进行二分法检索指定的值

        使用Arrays.binarySearch(数组名,查询值)方法可以对排序后的数组进行二分法检索指定的值。使用前提是当前数组必须是有序的,返回值为int,为负则查找失败,找到了返回下标。例如:

int[] arr1 = new int[]{1,2,3,4,6};
int index = Arrays.binarySearch(arr1,1);
System.out.println(index);

八、数组的常见应用场景        

        数组在实际编程中有很多常见的应用场景,其中之一就是存储一组数据进行统计分析,如计算平均值、最大值、最小值等。

        例如,可以使用以下方法获取数组中的最大值和最小值:

方法一:该方法使用交换顺序来寻找最大值,但查找完以后会污染数组,不能同时运行寻最大值方法和最小值方法。

 
/*获取数组里的最大值和最小值*/
public class TestFindArrayNum {
    public static void main(String[] args) {
        int[] arr = {500,11,12,100,11,13,1,3,5,205,7,9,2,4,6,8,400,0,300,10};
        findMaxNum(arr);
        //使用寻找最小值方法之前要先注释掉寻找最大值的方法
        //因为使用完寻找最大值的方法后会污染数组,整个数组都会变为最大值500
        //findMinNum(arr);
    }
    private static void findMaxNum(int[] arr) {
        int maxNum = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            if (arr[i + 1] > arr[i]) {
                maxNum = arr[i + 1];
            } else {
                arr[i + 1] = arr[i];
                maxNum = arr[i];
            }
        }
        System.out.println("数组中最大值是" + maxNum);
    }
    private static void findMinNum(int[] arr) {
        int minNum = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            if (arr[i + 1] < arr[i]) {
                minNum = arr[i + 1];
            } else {
                arr[i + 1] = arr[i];
                minNum = arr[i];
            }
        }
        System.out.println("数组中最小值是" + minNum);
    }
}

方法二:方法二代码更加简洁且不会污染数组

/*获取数组里的最大值和最小值*/
public class TestFindArrayNum2 {
    public static void main(String[] args) {
        int[] arr = {500,11,12,100,11,13,1,3,5,205,7,9,2,4,6,8,400,0,300,10};
        findMaxNum(arr);
        findMinNum(arr);
    }
    private static void findMaxNum(int[] arr) {
        int max = arr[0];
        for (int i = 1; i <= arr.length - 1; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }
        System.out.println("数组中最大值" + max);
    }
    private static void findMinNum(int[] arr) {
        int min = arr[0];
        for (int i = 1; i <= arr.length - 1; i++) {
            if (min > arr[i]) {
                min = arr[i];
            }
        }
        System.out.println("数组中最小值" + min);
    }
}

方法三

 
public class TestFindArrayNum3 {
    private int max;
    private int min;
    public int getMax() {
        return max;
    }
    public int getMin() {
        return min;
    }
    public void FindMaxAndMin(int[] arr ) {
        if(arr==null){
            System.out.println("输入的数组为空");
            return;
        }
        int i = 0;
        int len = arr.length;
        max = arr[0];
        min = arr[0];
        //两两分组,把较小的数挪到左边,较大的数挪到右边
        for(i = 0; i < len - 1; i += 2){
            if(arr[i]>arr[i + 1]){
                int tmp = arr[i];
                arr[i]= arr[i + 1];
                arr[i + 1]= tmp;
            }
        }
        //最小值放在各个分组的左边
        min = arr[0];
        for(i = 2; i < len ; i += 2){
            if(arr[i]<min){
                min = arr[i];
            }
        }
        //最大值放在各个分组的右边
        max = arr[1];
        for(i = 3; i < len; i += 2){
            if(arr[i]>max){
                max = arr[i];
            }
        }
        //如果数组中元素个数是奇数个,最后一个元素被分为一组,需要特殊处理
        if(len%2==1){
            if(max<arr[len - 1])
                max = arr[len - 2];
            if(min>arr[len - 1])
                min = arr[len - 1];
        }
    }
    public static void main(String[] args) {
        int[] arr={500,11,12,100,11,13,1,3,5,205,7,9,2,4,6,8,400,0,300,10};
        TestFindArrayNum3 f =new TestFindArrayNum3();
        f.FindMaxAndMin(arr);
        System.out.println("最大值是"+f.getMax());
        System.out.println("最小值是"+f.getMin());
    }
}

        除了获取最大值和最小值,还可以计算数组的平均值。一般情况下对数组计算均值,可以采用对数组求和,再除以数组长度。实现代码:

 
public double doubleArrAverage(double[] arr) {
    double sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    return sum / arr.length;
}

        但其中存在最大问题就是数组求和,如果数组内元素值较大或者数组元素非常多,很有可能出现内存溢出。解决这种问题,一种方法是采用每个元素除以数组长度,再对结果求和。实现代码:

public double doubleArrage(double[] arr) {
    double result = 0;
    for (int i = 0; i < arr.length; i++) {
        result += arr[i] / arr.length;
    }
    return result;
}

        另一种方法是,假定数组长度是动态的,当存在一个元素时,均值ave即为当前数组值arr[0]。当加入第二个个元素,第二个元素减去均值ave,得到的差值除以数组长度,再与均值ave相加,即可得到数组均值。以此类推,直到数组所有元素参与计算,也就完成了整个数组均值计算。实现代码:

 
public double doubleArrage(double[] arr) {
    double result = arr[0];
    for (int i = 1; i < arr.length; i++) {
        double temp = arr[i];
        result += (temp - result) / (i + 1);
    }
    return result;
}

        在实际编程中,数组还可以用于对用户输入的成绩进行排序和计算平均分。例如:

Scanner scanner = new Scanner(System.in);
int[] scores = new int[5];
for (int i = 0; i < scores.length; i++) {
    scores[i] = scanner.nextInt();
}
Arrays.sort(scores);
double average = Arrays.stream(scores).average().orElse(Double.NaN);

        这段代码演示了如何使用数组来收集用户输入的成绩,对这些成绩进行排序,并计算平均值。

        数组的常见应用场景还包括排序算法教学、搜索引擎索引、股票市场分析等。在排序算法教学中,可以使用数组来展示冒泡排序、选择排序等算法;在搜索引擎索引中,可以使用数组作为倒排索引的一部分,快速检索关键词;在股票市场分析中,可以使用数组存储股票价格,分析市场趋势。


http://www.kler.cn/a/412542.html

相关文章:

  • Hot100 - 除自身以外数组的乘积
  • 杰发科技AC7803——不同晶振频率时钟的配置
  • git: 修改gitlab仓库提交地址
  • Python学习34天
  • JDBC 批量调用数据库 SQL, 函数与存储过程
  • 人体特定吸收率 (SAR) 分布建模
  • 项目自动化部署,持续集成/持续交付(CI/CD)工具有那些?他们的优劣势分别是什么?共计15个工具进行对比分析。
  • C++虚函数面试题及参考答案
  • 如何为 ext2/ext3/ext4 文件系统的 /dev/centos/root 增加 800G 空间
  • ms-hot28 合并两个有序数组
  • 基于RAG的企业文档智能检索系统设计与实践
  • TCP/IP 协议:网络世界的基石(2/10)
  • C/C++语言基础--C++字符串实现的三种方法(eager copy、cow、sso)
  • JavaEE 【知识改变命运】03 多线程(2)
  • java——@Transactional 在哪些情况下会失效?
  • 基于Java的Nacos云原生动态服务发现、配置和服务管理平台设计源码
  • deepin社区与此芯科技完成产品兼容性认证
  • 南京移动携手南大打造江苏首个直通高校智算项目
  • docker compose启动springcloud微服务案例
  • 数据结构 (13)串的应用举例
  • Day50 | 动态规划 :线性DP 最大子数组和不同的子序列
  • 如何启用本机GPU硬件加速猿大师播放器网页同时播放多路RTSP H.265 1080P高清摄像头RTSP视频流?
  • 阿里发布 EchoMimicV2 :从数字脸扩展到数字人 可以通过图片+音频生成半身动画视频
  • Android.mk里如何指定编译模块的输出路径
  • Day47 | 动态规划 :线性DP 最长公共子序列最长公共子数组
  • 解决 IDEA 突然出现 unresolved class reference 问题