期末考试结束之后,需要对学生成绩进行全面的总结分析,其中包括统计每一门课程的班级平均成绩、成绩排名及每位同学的成绩统计等。
进行这类班级成绩分析,首先需要将所有学生的各科成绩进行存储,然后才能进行统计分析处理,要存储这种大批量的数据就需要使用一种新的数据存储方式—— 数组 。
数组是有限个具有相同类型的数据的有序集合,每个数组有固定的长度,在内存中占一片连续的存储空间。数组中的数据称为数组元素,每个数组元素用数组名和下标来唯一地标识,下标就是数组元素在数组中的位置(即序号)。根据数组下标的个数,数组分为一维数组、二维数组和多维数组。
在Java语言中,数组被当作一个对象处理,是一种引用数据类型。
视频2-5
一维数组相当于一个数列。在Java语言中,数组也要遵循“先声明、后使用”的原则。声明数组时需要定义数组的名称、维数和数组元素的类型。
声明一维数组的语法格式如下。
或
其中,数组元素的数据类型可以是基本类型,也可以是引用类型。数组名必须是一个合法的标识符。例如,要保存一批学生的成绩,可以声明一个名为score、元素类型为float的数组,定义方式为:
或
Java在声明数组时,只是建立了一个数组的引用,此时并没有为数组元素分配内存空间。
在进行了数组声明之后,使用new操作符创建数组,为数组分配存储空间后,数组才真正占用了一片连续的内存单元,数组的长度在此时被确定。创建数组的语法格式如下。
例如:
可以将声明数组和创建数组两个步骤合在一起,用一条语句来实现,其语法格式为:
或
例如:
数组一旦创建以后,就有了确定的长度,数组中各元素通过下标来标识,下标从0开始,最大下标值为数组长度减1。对于score数组,系统为该数组的10个元素分配空间,10个元素分别为score[0]、score[1]、score[2]、……、score[9]。如果数组元素的类型是基本数据类型,数组元素都自动初始化为默认值。数组存储格式如图2-6所示。
图2-6 数组存储格式
和简单变量一样,数组也可以进行初始化。在声明数组的同时给数组赋予初值。其语法格式如下:
或
此时,系统会自动按所给初值的个数计算出数组的长度并分配相应的空间,并把初值存入各元素所占用的内存单元。例如:
注意: 对于一个已经分配了存储空间的数组,其长度是不能再被改变的。
在Java语言中,对数组的访问只能通过数组元素进行,数组元素的引用格式为:
其中,下标可以为整型常数或整型表达式,如a[3],b[i](i为整型),score[2*i]等。
在实际应用中,经常通过循环来控制对数组元素的访问,访问数组的下标随循环控制变量的变化而变化。
【例2-17】 求30个学生的平均成绩。
说明: 在该程序中给数组输入数据和计算平均成绩分别用两个循环来处理。
for增强语句也称为for each循环,基本语法格式为:
例如,对【例2-17】中数组score的访问,可使用如下语句。
该循环输出score数组中的所有元素。
(1)数组长度属性
数组作为对象,所有的数组都有一个属性 length ,表示数组的长度,使用方法为:
例如:
则num.length的值为10。
访问数组元素时,下标取值范围为从0至 数组名.length-1 ,如果下标超出范围,则运行时将产生“数组访问越界异常”。
(2)数组工具类Arrays
Java系统提供了一个工具类Arrays,该类提供用于数组操作的各种方法。如对数组的排序和查询等操作可直接调用Arrays中的相应方法完成。如:
binarySearch()方法采用二分查找法,所以要求数组元素必须有序排列。如果数组中包含关键字,则返回一个正数;否则返回一个负数。
【例2-18】 产生20个100以内的随机整数,对其进行排序并输出,查找其中是否包含数值85。
【例2-19】 有一个整数数组,其中存放着序列1,3,5,7,9,11,13,15,17,19。请将该序列逆序存放并输出。
将一个数组中的元素逆序存放,就是先将数组中的第一个元素与最后一个元素交换,再将第二个元素与倒数第二个元素交换,以此类推,共交换(数组长度/2)次即可,程序如下。
二维数组常用于表示一张二维表格。Java中,二维数组可看作由一维数组组成的数组,即二维数组中每个元素又是一个一维数组。
和一维数组的创建过程一样,二维数组可以先声明再创建,也可以在声明的同时进行创建。
声明二维数组的语法格式:
或
其作用是仅声明一个二维数组,并不为其分配存储空间。
例如:
创建二维数组则可以用以下多种方式完成。
(1)同时为二维数组的行和列分配存储空间
基本语法格式:
例如:
(2)先指定二维数组的行数,再分别为每一行指定列数
例如:
Java中,二维数组中每一行的元素个数可以不同,如:
(3)通过初始化创建二维数组
例如:
此时,系统会自动按初值表中的数据个数计算出数组的长度并分配相应的空间。该例中的二维数组arrayA由3个一维数组组成,每个一维数组的长度都是3。
再如:
创建了一个不规则的二维级数,共4行,每个的元素个数分别为4、2、3、2。
二维数组中各元素通过两个下标来区分,每个下标的最小值为0,最大值为行数或列数减1。二维数组元素访问格式:
如:arrayA[i][j]表示第 i 行第 j 列的元素。
二维数组也具有length属性,数组名.length表示二维数组的行数,数组名[行下标].length则表示该行的列数。
在实际应用中,需要通过二重循环来控制对数组元素的访问。
【例2-20】 二维数组的定义、初始化及输出。
运行结果如图2-7所示。
图2-7 【例2-20】运行结果
【例2-21】 二维数组动态创建示例。
运行结果如图2-8所示。
图2-8 【例2-21】运行结果
说明: 本例首先确定主数组的长度(行数),而子数组的长度(每行的列数)则在循环中逐个创建,大小不同。引用数组元素时,必须保证访问的数组元素在已创建的空间范围内。
【例2-22】 求一个3×3矩阵两条对角线上的元素之和。
一个3×3的矩阵可以看作一个二维数组,其两条对角线上元素的特点是:1)行号、列号相等;2)行号、列号之和等于2。程序如下:
视频2-6
字符串是程序设计中经常使用的一种数据类型,Java中对字符串的处理通常使用两个系统类String和StringBuffer,这两个类都在java.lang包中。String类创建的字符串是常量,是不可更改的,每次需要改变字符串时都要创建一个新的对象来保存改变后的内容。StringBuffer类创建的字符串是变量,其内容是可以改变的。所以,String类常用于创建不经常对内容进行更改的字符串,StringBuffer类常用于对一个字符串进行修改(例如插入、删除等操作)的情况。
(1)字符串创建
1)使用字符串常量直接初始化一个字符串对象。
在Java中,字符串常量是用双引号括起来的字符序列,又称为无名字符串对象。用字符串常量直接初始化一个String类的对象是创建字符串对象最常用的方法。例如:
Java语言中还定义了一个String对象的运算符“+”,它的作用是连接两个字符串。上面的语句也可以写成:
2)使用String类提供的构造方法创建字符串对象。
Sting类提供了多个不同的构造方法,允许使用不同的数据源为字符串对象提供初始值。
例如:
已经创建的字符串对象可以在任何允许使用字符串的地方使用,例如:
【例2-23】 字符串使用示例。
运行结果:
(2)常用字符串操作
对字符串的操作是通过String类提供的方法实现的。一旦一个String对象被创建,将无法改变字符串的内容。但仍然可以对字符串对象执行各种类型的操作,比如访问字符串、子字符串搜索、子字符串截取、字符串比较、修改等。需要明确的是,每次需要改变字符串时都要创建一个新的String对象来保存改变后的内容,而原始的字符串不变。下面介绍几种常用的字符串操作方法。
1)获取字符串长度的方法。
int length()方法返回字符串的长度,这里的长度指的是字符串中Unicode字符的数目。例如:
len的值为10。由于Java采用Unicode编码,所有字符都占用16位长,因此汉字和其他符号一样都是一个字符。
2)搜索字符或字符串的方法。
indexOf()和lastIndexOf()方法用于在给定的字符串中搜索指定的字符或字符串。在String类中,定义了很多indexOf()和lastIndexOf()方法,这些方法的方法名相同,但参数不同,这种定义方式在面向对象的程序设计中称为方法的重载。下面列出了indexOf()和lastIndexOf()的几种重载形式。
从给定字符串的左侧开始搜索指定的字符,并返回其首次出现的索引。
从给定字符串的右侧开始搜索指定的字符,并返回其首次出现的索引。
从给定字符串左侧startIndex的索引开始搜索指定的字符,并返回其首次出现的索引。
从给定字符串右侧startIndex的索引开始搜索指定的字符串,并返回其首次出现的索引。
从给定字符串左侧开始搜索指定的字符串,并返回其首次出现的索引。
从给定字符串右侧开始搜索指定的字符串,并返回其首次出现的索引。
从给定字符串左侧startIndex的索引开始搜索指定的字符串,并返回其首次出现的索引。
从给定字符串右侧startIndex的索引开始搜索指定的字符串,并返回其首次出现的索引。
需要说明的是,在字符串中第一个字符的索引是0,第二个字符的索引是1,依此类推,最后一个字符的索引是length()-1。如果没有搜索到指定的字符或字符串,返回-1。
【例2-24】 indexOf()和lastIndexOf()方法的使用。
输出结果为:
3)截取子字符串的方法。
char charAt(int index)方法得到字符串中指定索引位置上的字符。例如:
则ch1中的字符为'J'。
void getChars(int start,int end,char objstr[],int objstrStart)方法用于在字符串对象中截取子字符串。参数start指定了子字符串开始位置的索引,end指定了子字符串结束位置的下一个字符的索引。因此子字符串包含了从索引start到索引end-1的字符。获得的子字符串存入数组objstr,起始位置由objstrStart指定。注意:必须确保数组objstr有足够大的空间以保证能容纳所获得的子字符串中的字符。
【例2-25】 getChars()方法的使用。
运行结果为:
String substring(int startIndex)方法用于截取指定位置后面的内容作为子字符串。有两种形式:
前者返回给定字符串中从beginindex起到字符串尾为止的一个子串;后者返回给定字符串中从beginindex起到endindex-1的一个子字符串,该子字符串长度为endindex-beginindex。
【例2-26】 显示星期日到星期六的名称。
程序的运行结果为:
4)字符串比较方法。
equals()和equalsIgnoreCase()方法都是用来检验两个字符串是否相等的,不同的是,后者比较时不区分字母大小写。两个方法的返回值均为布尔型。例如:
compareTo()方法和compareToIgnoreCase()方法 这两个方法用于比较当前字符串与参数中指定的字符串的大小,后者在比较时不区分字母大小写。返回值为整型。如果返回值大于0,则当前字符串比参数中的字符串大;如果返回值小于0,则当前字符串比参数中的字符串小;若两个字符串相等,则返回值为0。
5)字符串连接方法。
concat(String str)方法的参数为一个String类对象,作用是将参数中的字符串str接到当前字符串的后面。例如:
则字符串str2的内容为"欢迎学习Java语言"。
6)删除字符串两端空格的方法。
trim()方法的功能是将一个字符串两端的空格字符截掉,得到一个两端都不含有空格的新字符串。例如:
输出为:欢迎学习JAVA.
StringBuffer类的每一个对象通过调用该类的一些方法可以改变自身的长度和内容,所以用StringBuffer类创建的字符串对象也称为字符串变量。
(1)创建字符串变量
用StringBuffer类创建字符串变量的过程与String类对象的创建过程极其相似。字符串变量通过调用StringBuffer类的构造方法进行创建。其构造方法主要有以下几个。
例如:
说明: 每个StringBuffer对象都有一个容量,只要其字符序列的长度不超过其容量,就无须分配新的内部缓冲数组;如果内部缓冲数组溢出,StringBuffer对象的容量将自动增大。
(2)StringBuffer类对象的操作
对字符串变量的操作是通过StringBuffer类提供的方法实现的。StringBuffer类提供了很多对字符串变量进行访问的方法,在这些方法中绝大部分与String类中的方法相同。同时,StringBuffer类还提供了用于字符串变量修改和扩充的方法。下面重点介绍StringBuffer类的几种常用字符串操作方法。
1)字符串访问方法。
int capacity()方法用于获取当前StringBuffer对象的容量。
int length()方法用于获取当前StringBuffer对象的长度(字符数)。
2)字符串修改方法。
setCharAt(int index,char ch)方法将指定的字符ch放到index指定的位置上。例如:
replace(int a,int b,String str)方法使用新字符串str替换当前字符串变量中从起始位置a到结束位置b的内容。
insert(int offset,char ch)方法和insert(int offset,String str)方法用于在当前字符串对象的offset位置插入字符ch或字符串str。
例如:
则s为"welcome"。
append(String str)方法将给定的字符串追加到当前字符串变量的末尾。
例如:
则s为"welcome"。
deleteCharAt(int a)方法和delete(int a,int b)方法,前者用于删除指定索引位置处的字符;后者用于删除当前字符串变量中从起始位置a到结束位置b的内容。
【例2-27】 StringBuffer类常用方法的使用。
任务2-4
统计全班同学的期末考试成绩,共有四门考试科目,分别是:高等数学、大学英语、Java程序设计和MySQL数据库。假设班级有40名同学,以此确定数组的大小。程序代码请扫描二维码下载。
程序运行示例如图2-9所示。
图2-9 程序运行示例
创建一个具有20个整数的数组,然后对数组进行以下操作。
1)对数据进行排序。
2)在数组中添加任意一个整数,使数组仍然保持有序。
工单2-4
3)从数组中删除某个数据。