Java基础-第05章:数组[云图智联]

免费学习视频欢迎关注云图智联:https://e.yuntuzhilian.com/

1. 数组概述

1.1 为什么需要数组

  在执行程序的过程中,经常需要存储大量的、数据类型相同的、用途相近的数据,比如全班40个同学的成绩、梁山108名好汉的名字等等。如果还使用之前的变量、一个一个的来存储和处理就会非常麻烦。这就需要一个高效的、组织良好的方法。Java和许多其他高级语言都提供了一种称作“数组”(array)的数据结构,可以用它来存储一个元素个数固定且类型相同的有序集合。使用它来集中操作数据就会便捷很多。

1.2 什么是数组

1.2.1  在Java中,通常把数组也看作一个变量,用于将相同数据类型的数据集合存储在内存中。
1.2.2  数组的基本要素:
  1. 标识符。和变量一样,数组也要有一个名称,称为标识符,用于区分不同的数组。
  2. 数组元素。数组中存放的各个数据就称为数组元素。
  3. 数组下标。为了正确地区分数组的每个元素,需要对它们进行编号,这个编号就称为数组下标。(注意下标是从0开始)。
  4. 元素类型。数组元素应该是同一数据类型,即元素类型。

1.3 如何使用

1.3.1   声明数组:为了在程序中使用数组,必须声明一个引用数组的变量,并指明数组的元素类型,语法格式为:

数据类型[] 数组名;

或者

数据类型 数组名[];     //允许,但不推荐。这是C/C++语言的风格,被Java采纳后以适用于C/C++程序员。

比如:

int[] scores;       //声明了一个名字为scores(分数)的、数据类型为int的数组
String names[];     //声明了一个名字为names(姓名)的、数据类型为String的数组,允许,但不推荐

  现在我们来关注一下之前经常编写的、但又有些陌生的main()方法:"public static void main(String[] args){}",其中()里的"String[] args"就是一个String类型的数组,名称为args(arguments的简写,意为”内容、参数“)。

1.3.2   创建数组:不同于声明一个基本数据类型的变量,声明一个数组变量时并不给数组分配任何内存空间。所以使用下面的语法用 new 操作符创建数组,并将它的引用赋给一个变量:

数组名=new 数据类型[数组长度];      //这条语句作了两件事:1.使用 “new 数据类型[数组长度]”创建了一个数组;2.将这个数组的引用赋值给变量“数组名”;

  关于“引用”的说明:目前来说,我们可以暂时的、简单的把它作为一个名词来理解:可以代表一个真实事物的代号,比如一个人的名字就是对这个人的引用,一个超链接的表面值就是对它的真实地址的引用;

声明一个数组变量、创建数组、将数组的引用赋值给变量,这三个步骤可以合并在一条语句中:

数据类型[] 数组名=new 数据类型[数组长度];

比如:

int[] scores=new int[40];
String[] names=new String[108];

1.3.3   给数组元素赋值:数组名[下标]=值;,比如:

scores[0]=86;
names[0]="武松";

1.3.4   也可以将声明数组、创建数组和赋值在一条语句中完成:

数据类型[] 数组名={值1,值2,值3,……,值n};

比如:

double[] prices={20.8,11.9,0.99,20,0.1};    //double类型的价格数组
char[] chars={'a','b','c','d','e'};         //char类型的字符数组

注意:直接创建并赋值的方式必须在一条语句内一并完成。下面这种方式是错误的:

char[] chars;
chars={'a','b','c','d','e'};    //错误

1.4 注意

1.4.1   数组一旦创建,其长度(即数组元素的个数)是不可改变的,如果越界访问【数组下标的范围为:0-(数组长度-1)】,程序会报错。
1.4.2   因此,当我们需要使用数组的长度值时, 一般不直接使用具体的值,而是使用数组名.length

2. Arrays类的常用方法:

java.util.Arrays类包含一些实用的静态方法用于常见的数组操作,包含但不限于:

方法名称说明
boolean equals(array1,array2)比较数组array1和array2是否相等
void sort(array)对数组array的元素进行升序排列
String toString(array)将数组array转换成一个字符串
void fill(array,val)把数组array 的元素填充为val
ArrayType copyOf(array,length)把数组array复制成一个长度为length的新数组,返回类型与复制的数组一致
int binarySearch(array, val)查询值val在数组array中的下标(要求数组中元素已经升序排列)如果没有找到,则返回一个负整数

2.1 equals()方法:比较两个数组是否严格相等,如果它们对应的元素都相等,那么返回true,否则返回false。

int[] arr1={2,4,7,10};
int[] arr2={2,4,7,10};
int[] arr3={4,2,7,10};
System.out.println(Arrays.equals(arr1,arr2));       //返回true
System.out.println(Arrays.equals(arr1,arr3));       //返回false

2.2 sort()方法:可以使用sort()方法对整个或部分数组进行升序排序

int[] arr4={2,4,7,10,3,5};
Arrays.sort(arr4);              //将整个arr4数组进行升序排列;
Arrays.sort(arr4,0,4);          //将arr4数组中的、从arr4[0]到arr4[4-1]的元素进行升序排列;
//Arrays还提供了一个parallelSort()方法,它的作用与sort()方法相同,但当你的计算机有多个处理器时,前者将更加高效。

2.3 toString()方法:将数组转换成一个固定格式的字符串

int[] arr5={2,4,7,10,3,5};
System.out.println(Arrays.toString(arr5));      //输出:[2, 4, 7, 10, 3, 5]
char[] chars= {'b','y','p','q','d'};
System.out.println(Arrays.toString(chars));     //输出:[b, y, p, q, d]

2.4 fill()方法: 填充(或替换)数组的全部或部分元素

int[] arr5={2,4,7,10,3,5};
char[] chars= {'b','y','p','q','d'};
Arrays.fill(arr5, 6);                           //用6替换arr5的所有元素
Arrays.fill(chars,0,3, 'a');                    //用'a'替换chars中从chars[0]到chars[3-1]的元素
System.out.println(Arrays.toString(arr5));      //输出:[6, 6, 6, 6, 6, 6]
System.out.println(Arrays.toString(chars));     //输出:[a, a, a, q, d]

2.5 copyOf()方法:把数组复制成一个长度为length的新数组

int[] arr6={2,4,7,10,3,5};
char[] chars= {'b','y','p','q','d'};
int[] arrCopy=Arrays.copyOf(arr6, 5);
System.out.println(Arrays.toString(arrCopy));       //输出:[2, 4, 7, 10, 3]
char[] charsCopy= Arrays.copyOf(chars, 6);          //若新长度大于原长度,将用此类型的默认值补充
System.out.println(Arrays.toString(charsCopy));     //输出:[b, y, p, q, d, □]

2.6 binarySearch()方法: 采用二分查找法在数组中查找指定元素。要求此数组已经升序排列。如果存在则返回此元素的下标;如果不存在,则假定按顺将此元素插入数组中,并返回: -(假定插入后的下标+1)。

int[] arr7={2,4,7,10,20,25};    
System.out.println("7的下标为:"+Arrays.binarySearch(arr7, 7));  //输出:7的下标为:2
System.out.println("12的下标为:"+Arrays.binarySearch(arr7, 12));    //输出:12的下标为:-5,因为:假如存在元素”12“的话,它的下标应为:4

3. 数组的常见应用

  处理数组时,经常会用到for循环,这是因为:(1)数组中的所有元素都是同一类型的,可以使用for循环以同样的方式反复的处理这些元素;(2)数组的长度是已知的,所以很自然的就使用for循环;以下列出了数组了几种常见操作:

3.1 使用循环来初始化数组和显示数组元素:

public static void main(String[] args) {
    java.util.Scanner input = new java.util.Scanner(System.in);
    System.out.println("请输入5位同学的成绩:");      
    int[] scores=new int[5];    
    for (int i = 0; i < scores.length; i++) {
        scores[i]=input.nextInt();
    }
    System.out.println("5位同学的成绩分别为:");  
    for (int i = 0; i < scores.length; i++) {
        System.out.print(scores[i]+"\t");
    }
}

效果图如下:

3.2 求数组的最大值:

3.2.1   思路:类似于打擂台,假设第一个人是擂主,后面的选手逐个与他比试,如果他胜利,当前擂主还是他,如果失败,那么胜利的人成为新的擂主...同理,我们将数组的第一个元素假设为最大值,并将它的值另存入一个变量max中,再通过循环,将其后的每一个元素逐一与max比较,如果这个元素大于max,则将max的值更新为当前这个元素的值。
3.2.2   举例说明:

int max = nums[0];
for(int i = 1; i < nums.length; i++){    //从第二个元素开始,到最后一个结束
    if(nums[i] > max){
        max = nums[i];
    }
}

3.3 向数组中插入1个元素:

3.3.1   要求:1.数组已经升序或降序排列;2.数组中剩有一个空元素没有赋值;
3.3.2   思路(以降序数组为例):1.先通过循环找到新增元素要插入的位置;2.将此位置后的元素依次后移;3.将新增元素插入到此位置;
3.3.3   举例说明:

int[] arr = new int[9];     // 长度为6的数组
int num=15;                 // 新增的元素
int index = 0;              // 新增元素要插入的位置
 //……省略为数组赋值(赋 5 个值)
 for(int i = 0; i < arr.length; i++){
        if(num > arr[i]){
                index = i;      // 找到并保存新增元素要插入的位置
                break;
        }
  } 
  //元素后移
  for(int j = arr.length-1; j > index; j--){
         arr[j] = arr[j-1];
  }
  //插入新增元素
  arr[index] = num;     

过程演示如下:

4.二维数组

4.1 什么是二维数组

4.1.1   之前我们所说的数组其实都是”一维数组“,它存储的是一维的、线性的元素集合。二维数组和一维数组结构类似,是一维数组的进阶。它可以存储矩阵或表格式的数据。二维数组的每一个元素又是一个一维数组。 比如下列这样成绩表:

姓名Java成绩HTML成绩JS成绩Python成绩
唐僧98968792
悟空100100100100
八戒70707070
沙僧80858688

如果使用二维数组来存储即:

int[][] scores={{98,96,87,92},{100,100,100,100},{70,70,70,70},{80,85,86,88}};

4.1.2   二维数组的基本要素和一维数组类似:
  1.标识符:二维数组的名字,用于区分不同的数组。比如:scores
  2.数组下标:二维数组使用两个索引来指定存取数组的元素。比如:scores[1][1]即:“第二行第二列的、悟空的HTML成绩,100”。   3.元素类型:二维数组中的所有数组元素的数据类型也都是一样的。
  4.数组元素:二维数组的每一个数组元素又是一个完整的一维数组(这句话是理解二维数组的关键)。    

4.2 如何使用二维数组

4.2.1   声明数组:

数据类型[][] 数组名;

或者 数据类型 数组名[][]; //允许但不推荐 比如:

int[][] scores;

4.2.2   创建数组并赋值给一个引用:

数组名 = new 数据类型[数组长度1][数组长度2];  
数组名 = new 数据类型[数组长度1][];  

比如:

scores=new int[4][4];

或者:

scores=new int[4][];

注意:“数组长度1”是必须要指定的,用以声明二维数组的长度,分配相应的内存空间。“数组长度2”在分配空间时可以暂时不指定,但是在使用时还是要指定。
4.2.3   当然,声明和创建可以二合一:

数据类型[][] 数组名=new 数据类型[长度1][长度2];  

4.2.4   赋值:

数组名[下标1]= new 数据类型[长度];   

比如: scores[2]=new int[4]; 或者:
数组名[下标1][下标2]=值; 比如: scores[3][2]= 86; 4.2.5   当然,声明和赋值也可以进一步合并: 数据类型[][] 数组名={{值1,值2},{值3,值4,值5},{值6,值7,值8,值9}}; //前文中的示例即是这种形式

4.3 多维数组

  使用二维数组可以表示矩阵或表格形式的数组结构,如此推广,我们还可以使用三维数组来表示立体形式的数据结构。比如前文中,如果每一个人物的每一科成绩不再是单次成绩,而是5次的成绩单,就可以使用三维数组来方便的存储。继续如此推广,还有n维的数据结构,即多维数组。当然,三维及以上的数组很少会用到,了解即可。

5.习题:

5.1 需求说明:

  在中国古代,对男子的年龄称谓如下所示:
  0-9:稚子    10-19:束发    20-29:弱冠    30-39:而立    40-49:不惑    50-59:知天命    60-69:花甲    70-79:古稀    80-89:耄(mào)耋(dié)    90-99:鲐(tái)背(bèi)。   现请编程实现一个功能:任意输入一个人的年龄,可以判断他在古代的年龄称谓。要求如下:
  (1)此功能可以无限执行,直到输入一个非数字则结束程序;
  (2)如果输入的年龄>=100或<0,给出错误提示并实现重新输入;
  (3)要求使用数组存储年龄的古代称谓;
  (4)控制代码量在30行以内;

5.2 分析:

  1.对于第1个要求,我们可以使用while循环来实现,循环条件为”输入的是一个数字“;
  2.对于第2个要求,仍然可以使用while循环来实现,只不过循环的条件为”年龄>=100或<0“;
  3.内层while循环的循环操作为:根据用户的输入来输出对应的称谓。
  4.对于第4个要求,显然是在提示我们”使用数组来存储的古代称谓“并且不能简单的堆砌10个if-else结构来判断。那么应该使用什么更简便的办法来压缩代码量呢?不急,我们先创建好这个数组:      

String[] alias= {"稚子","束发","弱冠","而立","不惑","知天命","花甲","古稀","耄耋","鲐背"};    //alias:别名、别称

  仔细分析我们会发现:每一个别名的下标刚好就是它对应的年龄段的第一个数字!所以,我们可以先分解出用户输入的年龄值的10位上的数字,把它作为下标,即可找到对应的元素,即称谓!

5.3 参考代码:

public static void main(String[] args) {
    String[] alias= {"稚子","束发","弱冠","而立","不惑","知天命","花甲","古稀","耄耋","鲐背"};
    Scanner input = new Scanner(System.in);
    System.out.println("请输入一个年龄:");
    //创建布尔变量,标记输入的是否是数字
    boolean isRight=input.hasNextInt();
    while(isRight) {  //如果输入的是一个数字,则循环继续
        int age=input.nextInt();
        while(age>=100||age<0) {    //如果输入的年龄不合法,则循环继续
            System.out.println("年龄输入错误,请重新输入:");
            age=input.nextInt();
        }
        int index=age/10;   //分解得到10位上的数字
        System.out.println("他的年龄称谓是:"+alias[index]);
        System.out.println("请输入一个年龄:");
        isRight=input.hasNextInt();
    }
    System.out.println("功能结束!");        
}
//全部代码,约25行

6. 常用单词

1. array:数组
2. length:长度
3. sort:排序
4. max(maximum):最大值
5. min(minimum):最小值
6. fill:填充
7. copy:复制
8. search:搜索
6. info:信息
7. out of bounds:越界/出界

免费学习视频欢迎关注云图智联:https://e.yuntuzhilian.com/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值