精讲:JAVA之一维数组的使用

一、数组的概述

1.为什么需要数组

假如有如下需求,你会怎么处理呢?

需要统计某公司50个员工的工资情况,例如计算平均工资、找到最高工资等。用之前知识,首先需要声明`50个变量`来分别记录每位员工的工资,这样会很麻烦。因此我们可以将所有的数据全部存储到一个容器中统一管理,并使用容器进行计算。

        现在的你,也许只能想到定义50个变量去保存员工的工资。但是如果员工有一万个呢?显然使用变量保存员工工资的做法是不靠谱的。我们很自然地想到能够有一个可以保存多个数据的容器,这就引出了数组。

2.数组的介绍

a)定义

        数组(Array),是多个相同类型数据按一定顺序排列集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。

b)数组中的相关概念

数组名、下标(或索引)、元素、数组的长度

c)数组的特点

  • 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
  • 创建数组对象会在内存中开辟一整块连续的空间。占据的空间的大小,取决于数组的长度和数组中元素的类型。
  • 数组中的元素在内存中是依次紧密排列的,有序的
  • 数组,一旦初始化完成,其长度就是确定的。数组的长度一旦确定,就不能修改
  • 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
  • 数组名中引用的是这块连续空间的首地址
知识点回顾:基本数据类型和引用数据类型
基本数据类型:byte \ short \ int \ long ;float \ double ; char \ boolean
引用数据类型:类、数组、接口、枚举、注解、记录

d)数组的分类

①按元素类型分类:
  • 基本数据类型元素的数组:每个元素位置存储基本数据类型的值
  • 引用数据类型元素的数组:每个元素位置存储对象(本质是存储对象的首地址)(在面向对象部分讲解)
②按维度分类:
  • 一维数组:存储一组数据
  • 二维数组:存储多组数据,相当于二维表,一行代表一组数据,只是这里的二维表每一行长度不要求一样。

二、一维数组的声明与初始化

1.一维数组的声明

a)格式:

//推荐
元素的数据类型[] 一维数组的名称;

//不推荐
元素的数据类型  一维数组名[];

b)举例:

int[] arr;
int arr1[];
double[] arr2;
String[] arr3;  //引用类型变量数组

 c)声明时的注意点

(1)数组的维度:在Java中数组的符号是[],[]表示一维,[][]表示二维。
(2)数组的元素类型:即创建的数组容器可以存储什么数据类型的数据。元素的类型可以是任意的Java的数据类型。例如:int、String、Student等。
(3)数组名:就是代表某个数组的标识符,数组名其实也是变量名,按照变量的命名规范来命名。数组名是个引用数据类型的变量,因为它代表一组数据。
(4)Java语言中声明数组时不能指定其长度(数组中元素的个数)。 例如: int a[5]; //非法

2.一维数组的初始化

a)静态初始化

  • 如果数组变量的初始化和数组元素的赋值操作同时进行,那就称为静态初始化。
  • 静态初始化,本质是用静态数据(编译时已知)为数组初始化。此时数组的长度由静态数据的个数决定。
  • 一维数组声明和静态初始化的格式一:
格式

数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3,...};


    
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1,元素2,元素3,...};

举例

举例:

int[] arr = new int[]{1,2,3,4,5};//正确
//或
int[] arr;
arr = new int[]{1,2,3,4,5};//正确

注意:new关键字(创建数组使用的关键字。因为数组本身是引用数据类型,所以要用new创建数组实体。 )

  • 一维数组声明和静态初始化的格式二:
格式数据类型[] 数组名 = {元素1,元素2,元素3...};//必须在一个语句中完成,不能分成两个语句写
举例

int[] arr = {1,2,3,4,5};//正确。JVM会 类型推断

int[] arr;
arr = {1,2,3,4,5};//错误

b)动态初始化

  • 数组变量的初始化和数组元素的赋值操作分开进行,即为动态初始化。
  • 动态初始化中,只确定了元素的个数(即数组的长度),而元素值此时只是默认值,还并未真正赋自己期望的值。真正期望的数据需要后续单独一个一个赋值。
格式

数组存储的元素的数据类型[] 数组名字 = new 数组存储的元素的数据类型[长度];

数组存储的数据类型[] 数组名字;
数组名字 = new 数组存储的数据类型[长度];

举例

int[] arr = new int[5];

int[] arr;

arr = new int[5];

int[] arr = new int[5]{1,2,3,4,5};//错误的,后面有{}指定元素列表,就不需要在[]中指定元素个数了。

注意:数组有定长特性,长度一旦指定,不可更改。[长度]:数组的长度,表示数组容器中可以最多存储多少个元素。

三、一维数组的使用

1.数组的长度

  • 数组的元素总个数,即数组的长度。
  • 每个数组都有一个属性length指明它的长度,例如:arr.length 指明数组arr的长度(即元素个数)
  • 每个数组都具有长度,而且一旦初始化,其长度就是确定,且是不可变的。

2.数组元素的引用(调用)

a)如何调用数组中的一个元素?

        每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index)或下标,可以通过数组的索引/下标访问到数组中的元素。

        数组中元素的索引从0开始的原因:数组中元素放在内存中时,会放入一个堆空间结构中,然后通过变量记录数组的首地址,而索引实际代表的是偏移量,对于第一个元素来讲偏移量就是0。即“Java中数组的下标从[0]开始,下标范围是[0, 数组的长度-1],即[0, 数组名.length-1] ”。

        需要补充的是:数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];

格式数组名[索引或下标]
举例

int[] arr = {1,2,3,4,5};

System.out.println("arr数组的长度:" + arr.length);
System.out.println("arr数组的第1个元素:" + arr[0]);//下标从0开始
System.out.println("arr数组的第2个元素:" + arr[1]);

//修改第1个元素的值
//此处arr[0]相当于一个int类型的变量
arr[0] = 100;
System.out.println("arr数组的第1个元素:" + arr[0]);

3.一维数组的遍历

将数组中的每个元素分别获取出来,就是遍历。for循环与数组的遍历是绝配。

举例:

public class ArrayTest5 {
    public static void main(String[] args) {
        int[] arr = new int[5];

        System.out.println("arr数组的长度:" + arr.length);
        System.out.print("存储数据到arr数组之前:[");
        for (int i = 0; i < arr.length; i++) {
            if(i==0){
                System.out.print(arr[i]);
            }else{
                System.out.print("," + arr[i]);
            }
        }
        System.out.println("]");

        //初始化
         /* 
         arr[0] = 2;
        arr[1] = 4;
        arr[2] = 6;
        arr[3] = 8;
        arr[4] = 10;
        */

        for (int i = 0; i < arr.length; i++) {
            arr[i] = (i+1) * 2;
        }

        System.out.print("存储数据到arr数组之后:[");
        for (int i = 0; i < arr.length; i++) {
            if(i==0){
                System.out.print(arr[i]);
            }else{
                System.out.print("," + arr[i]);
            }
        }
        System.out.println("]");
    }
}

四、数组元素的默认初始化值

        数组是引用数据类型,当我们使用动态初始化方式声明一个数组的之后,在未初始化之前,数组中的元素只有默认值。那么创建不同类型的数组,是否默认值也不相同呢?答案是肯定的。

        对于基本数据类型的数组而言,默认初始化值各有不同。对于引用数据类型而言,默认初始化值均为null(注意与0不同)。

举例证明:

public class ArrayTest7 {
    public static void main(String[] args) {
        //存储26个字母
        char[] letters = new char[26];
        System.out.println("letters数组的长度:" + letters.length);
        System.out.print("存储字母到letters数组之前:[");
        for (int i = 0; i < letters.length; i++) {
            if(i==0){
                System.out.print(letters[i]);
            }else{
                System.out.print("," + letters[i]);
            }
        }
        System.out.println("]");

       //存储5个姓名
        String[] names = new String[5];
        System.out.println("names数组的长度:" + names.length);
        System.out.print("存储姓名到names数组之前:[");
        for (int i = 0; i < names.length; i++) {
            if(i==0){
                System.out.print(names[i]);
            }else{
                System.out.print("," + names[i]);
            }
        }
        System.out.println("]");
    }
}

五、一维数组内存解析(重难点

1.java虚拟机的内存划分

        为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

(图中粉色区域即为内存)

2.一维数组在内存中的存储

区域名称作用
虚拟机栈用于存储正在执行的每个Java方法的局部变量表等。局部变量表存放了编译期可知长度 的各种基本数据类型、对象引用,方法执行完,自动释放。
堆内存存储对象(包括数组对象),new来创建的,都存储在堆内存
方法区存储已被虚拟机加载的类信息、常量、(静态变量)、即时编译器编译后的代码等数据。
本地方法栈

当程序中调用了native的本地方法时,本地方法执行期间的内存区域。因为java会调用c的库

程序计数器程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址

注意:目前与数组相关的内存结构只有“虚拟机栈”和“”。

    > 虚拟机栈:用于存放方法中声明的变量。比如:arr
    > 堆:用于存放数组的实体(即数组中的所有元素)。比如:1,2,3

3.用图解释

a)举例一

public static void main(String[] args) {
      int[] arr = new int[3];
      System.out.println(arr);//[I@5f150435
}

b)举例二

public static void main(String[] args) {

      int[] arr = new int[3];

      arr[0] = 5;

      arr[1] = 6;

      arr[2] = 7;

      System.out.println(arr[0]);

      System.out.println(arr[1]);

      System.out.println(arr[2]);

       

      //定义数组变量arr1,将arr的地址赋值给arr1

      int[] arr1 = arr;

      arr1[1] = 9;

      System.out.println(arr[1]); //9

}

六、习题巩固

a)案例一

升景坊单间短期出租4个月,550元/月(水电煤公摊,网费35元/月),空调、卫生间、厨房齐全。屋内均是IT行业人士,喜欢安静。所以要求来租者最好是同行或者刚毕业的年轻人,爱干净、安静。输出结果是:

public class ArrayTest {
      public static void main(String[] args) {
      int[] arr = new int[]{8,2,1,0,3};
      int[] index = new int[]{2,0,3,2,4,0,1,3,2,3,3};
      String tel = "";
      for(int i = 0;i < index.length;i++){
            tel += arr[index[i]];
      }
      System.out.println("联系方式:" + tel);
      }
}

b)案例二

        用一个数组,保存星期一到星期天的7个英语单词,从键盘输入1-7,显示对应的单词{"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}

import java.util.Scanner;

/**
 * @author 尚硅谷-宋红康
 * @create 14:37
 */
public class WeekArrayTest {
    public static void main(String[] args) {

        //1. 声明并初始化星期的数组
        String[] weeks = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};

        //2. 使用Scanner从键盘获取1-7范围的整数
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入[1-7]范围的整数:");
        int number = scanner.nextInt();

        if(number < 1 || number > 7){
            System.out.println("你输入的输入非法");
        }else{

            //3. 根据输入的整数,到数组中相应的索引位置获取指定的元素(即:星期几)
            System.out.println("对应的星期为:" + weeks[number - 1]);

        }
        
        scanner.close();

    }
}

c)案例三

从键盘读入学生成绩,找出最高分,并输出学生成绩等级。

  • 成绩>=最高分-10 等级为’A’

  • 成绩>=最高分-20 等级为’B’

  • 成绩>=最高分-30 等级为’C’

  • 其余 等级为’D’

提示:先读入学生人数,根据人数创建int数组,存放学生成绩。

public class ScoreTest1 {
    public static void main(String[] args) {

        //1. 根据提示,获取学生人数
        System.out.print("请输入学生人数:");
        Scanner scanner = new Scanner(System.in);
        int count = scanner.nextInt();

        //2. 根据学生人数,创建指定长度的数组 (使用动态初始化)
        int[] scores = new int[count];

        //3. 使用循环,依次给数组的元素赋值
        int maxScore = 0; //记录最高分
        System.out.println("请输入" + count + "个成绩");
        for (int i = 0; i < scores.length; i++) {
            scores[i] = scanner.nextInt();
            //4. 获取数组中元素的最大值,即为最高分
            if(maxScore < scores[i]){
                maxScore = scores[i];
            }
        }

        System.out.println("最高分是:" + maxScore);

        //5. 遍历数组元素,输出各自的分数,并根据其分数与最高分的差值,获取各自的等级
        char grade;
        for (int i = 0; i < scores.length; i++) {

            if(scores[i] >= maxScore - 10){
                grade = 'A';
            }else if(scores[i] >= maxScore - 20){
                grade = 'B';
            }else if(scores[i] >= maxScore - 30){
                grade = 'C';
            }else{
                grade = 'D';
            }
            System.out.println("student " + i + " socre is " + scores[i] + ", grade is " + grade);
        }
        //关闭资源
        scanner.close();

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程学无止境

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值