Java学习第四章:数组
- 4.1一维数组
- 4.1.1数组的定义
- 4.1.2数组的创建
- 4.1.3数组的内存模型
- 4.1.4数组的初始化
- 4.1.5数组的访问
- 4.1.6数组的属性
- 4.1.7数组的异常
- 4.2数组的排序查找
- 4.3数组的操作
- 4.3.1数组的遍历
4.1一维数组
数组是相同类型的数据按照顺序组合后的一种引用类型。数组可以看成是多个相同类型数据的组合,实现对这些数据的统一管理。数组的长度一旦确定后就不能更改,因此它是一个固定长度的结构。数组结构中每个存储的数据叫数组元素,数组元素由索引来定位。索引(或叫数组下标)是指当前元素相对于第一个元素的位移,因此第一个元素的下标就是0,第二个元素的下标就是1,以此类推。
4.1.1数组的定义
我们用方括号“[]”来区分普通变量和数组变量。见下面声明整型数组的例子:
int[] numbers;
上面的语句声明了一个数组numbers,它的元素都是整型的,但是现在并没有确定数组的长度,也就是说没有确定numbers里有多少个元素。
提示: 方括号“[]”既可以放在数据类型的后面,也可以放在数组名的后面,两者都可以标识一个数组的声明,但是第一种写法可读性更好些。
例如:
char[] c;
String strs[];
数组声明后,Java虚拟机就会给数组分配存储空间,情况如下图4.1所示。
4.1.2数组的创建
数组的长度在创建时指定,并且一旦指定就不能更改。创建数组有两种方式:
1.静态初始化
这种方式在声明的同时就直接初始化数组,同时也创建了数组空间。如:
int[] m = {3,75,234,41,16};
上面的语句运行后,就会创建一个数组m,这个数组的长度是5,他有5个元素,分别是3,75,234,41,16。
2.动态初始化
这·种方式只是按照指定的长度来创建数组空间,但是数组里的元素将初始化为缺省值(对字符来说,为’\u0000’),例如:
numbers = new int[6];
上面的语句运行后,会创建一个数组numbers,这个数组的长度是6,但是值都是0,使用这个数组前还需要进一步的赋值使之有效。
这种创建方式的语法是:
数组名 = new 数组类型[数组长度];
如:
char[] c = new char[128];
String[] strs = new String[10];
double[] incoming = new double[73];
4.1.3数组的内存模型
数组是存储多个相同类型数据的对象。数组的所有元素保存在堆内存中。
创建一个数组就是在堆中创建一个数组对象。数组创建后立即拥有默认值。索引从0开始。连续分配
例如:
int[ ] array ;
array = new int [4] ;
4.1.4数组的初始化
数组的元素通过下标来标识,下标表示当前元素相对于第一个元素的位移,因此从0开始。比如name[0]就表示name数组的第1个元素,name[4]就表示name数组的第5个元素。其中方括号“[]”中的整数就是下标(又叫索引),要注意下标的范围从0~数组长度-1,如果访问超过范围的下标,就会发生ArrayIndexOutOfBoundsException下标越界异常。
数组类型 数组名[ ] = {元素1,元素2,…}
或者
数组类型 数组名[ ] = new 数据类型[ ]{元素1,元素2,…}
数组的初始化的两种方式如下:
例4.1 创建数组并初始化。
class Array_sample1 {
public static void main(String args[]){
int a[];
a = new int[5];
for(int i=1;i<5;i++){
a[i-1] = i;
}
}
}
赋值后数组元素的值分别是1,2,3,4,5。
4.1.5数组的访问
数组元素的访问需要根据数组名和下标共同实现,格式如下图所示。
数组名[元素下标] = 元素值;
例4.2 数组元素的访问。
public class Array_sample2 {
public static void main(String args[]){
int num1[] = new int[5];
num1[0] = 32; //每个元素单独初始化
num1[1] = 543;
num1[2] = 17;
num1[3] = 8;
num1[4] = 95;
int num2[] = new int[10];
for(int i=0;i<10;i++){ //采用循环方式初始化
num2[i] = i+1;
}
System.out.println("第一个数组:");
for(int j=0;j<num1.length;j++){ //采用循环方式输出数组的所有元素
System.out.print(num1[j] +" ");
}
System.out.println();
System.out.println("第二个数组:");
for(int x=0;x<num2.length;x++){
System.out.print(num2[x] +" ");
}
}
}
4.1.6数组的属性
数组是引用类型,具有属性,常用的数组属性就是数组的长度length,在使用时需注意:
–数组的长度(length)必须>=0;
–length为只读。
–利用length遍历数组
例4.3 求数组最大值、最小值和平均值。
class ArrayMax {
public static void main(String args[]){
int a[] = {1,-12,33};
int sum = 0;
int max = a[0];
int min = a[0];
for(int i=1;i<a.length;i++){
sum = sum+a[i];
if(a[i]>max){
max = a[i];
}
if(a[i]<min){
min = a[i];
}
}
double ave = (double)sum/3;
System.out.println("平均值"+ave);
System.out.println("最大值"+max);
System.out.println("最小值"+min);
}
}
例4.4 数组应用例题。
假设队列中共有500人,每次从1开始数,数到3的人出队,下一个人接着从1开始数,编写程序找到最后剩下的人是哪一个。
public class Count3Quit {
public static void main(String args[]) {
// 用布尔值来标识每个人是否出队 出队为false,未出队为true 并将每个人的初始值都赋为true
boolean a[] = new boolean[500];
for (int i = 0; i < a.length; i++) {
a[i] = true;
}
/*leftNum:未出队的人数 countNum:取值为1、2、3, 每次从1开始数,数到3的人出队,下一个人接着从1开始数
index:数数的人的编号,取值范围0~500
*/
int leftNum = a.length;
int countNum = 0;
int index = 0;
// 循环数数,直到只剩下一个人,即leftNum的值为1
while (leftNum > 1) {
if (a[index] == true) {
countNum++;
if (countNum == 3) {
countNum = 0;
a[index] = false;
leftNum--;
}
}
index++;
// 如果数到第500个人,index回0,又从第1个人开始数
if (index == a.length) {
index = 0;
}
}
//循环遍历每个数数的人,找到值为false的并输出
for (int i = 0; i < a.length; i++) {
if (a[i] == true)
System.out.println("最后剩下的人是第" + (i + 1) + "的人");
}
}
}
4.1.7数组的异常
应用数组时会出现两种异常,一种是空指针异常,类名为java.lang.NullPointerException
,没有创建而直接使用数组时会产生该异常,另外一种是数组下标越界异常,类名是java.lang.ArrayIndexOutOfBoundsException
,访问数组时的下标超出数组的最大下标时产生该异常。
例4.5 数组空指针异常。
public class Array_exception1 {
public static void main(String args[]){
int a[] = null ;
a [0] = 1 ;
System.out.println(a[0]);
}
}
运行结果如下:
例4.6 数组下标越界异常。
class Array_exception2 {
public static void main(String args[]) {
// int a[]={1,2,3};
int a[] = new int[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
System.out.println(a[3]);
}
}
运行结果如下:
4.2数组的排序查找
排序是计算机程序设计中的常见工作,例如把无序的成绩列表按由大到小的顺序输出,排序的算法也较多,本节介绍较为经典的冒泡排序法。和排序一样,查找是指在数组中寻找特定元素的过程。例如,查找商品列表中某个价格的商品,查找订单列表中某一份订单等等,在本节中介绍一种常见的算法:二分查找法。排序和查找也经常结合起来应用。
冒泡排序法(Bubble Sort,也称之为气泡排序法)是一种简单的排序算法。它重复地走访过要排序的数组,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数组的工作是重复地进行直到没有再需要交换,也就是说该数组已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数组的顶端,故名冒泡排序。
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
冒泡排序流程至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。
下面我们通过一个例子来看一下冒泡排序。 例4.7 数组排序。
public class Array_BubbleSort {
public static void main(String[] args) {
int[] sort = { 1, 6, 2, 3, 9, 4, 5, 7, 8 };
System.out.print("排序前:");
for (int i = 0; i < sort.length; i++) {
System.out.print(sort[i] + " ");
}
System.out.println();
for (int i = 0; i < sort.length; i++) {
int temp = 0;
for (int j = sort.length - 1; j > 0; j--) {
if (sort[j] > sort[j - 1]) {
temp = sort[j];
sort[j] = sort[j - 1];
sort[j - 1] = temp;
}
}
}
System.out.print("排序后:");
for (int i = 0; i < sort.length; i++) {
System.out.print(sort[i] + " ");
}
}
}
例4.8 数组二分查找。
public class BinarySearch {
public static void main(String[] args) {
int[] sort = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int key = 6;// 需要查找的值
int locale = -1;// 记录 查找位置的变量
int low = 0;
int high = sort.length - 1;
while (high >= low) {
int mid = (low + high) / 2;
if (key < sort[mid])
high = mid - 1;
else if (key == sort[mid]) {
locale = mid;
break;
} else
low = mid + 1;
}
if (locale == -1)
System.out.println("数组中不存在元素" + key);
else
System.out.println("元素" + key + "在数组中的下标是" + locale);
}
}
冒泡排序法也可以用Java自带的java.util.Arrays类中的sort方法实现,用法如下: 例4.9 数组二分查找。
import java.util.Arrays;
class ArraySort_sample {
public static void main(String args[]){
int[ ] point = {1,6,2,3,9,4,5,7,8};
Arrays.sort(point);
for(int i=0;i<point.length;i++)
{
System.out.print(point[i]+" ");
}
}
}
4.3数组的操作
4.3.1数组的遍历
数组的遍历需要利用循环语句和数组下标,下面通过几个例子来学习数组的遍历。 例4.11 循环遍历字符串数组{"red","orange","yellow","green","blue","purple"}
,并将其打印:
class Array_traversal {
public static void main(String args[]){
String color[] = {"red","orange","yellow","green","blue","purple"};
for(int i=0;i<color.length;i++){
System.out.println(color[i]);
}
}
}
例4.12 求最高分和学号
例4.13 查找二维整型数组中的最大数及其位置。
public class MulArrayMax2 {
public static void main(String args[]) {
int array[][] = { { 23, 2, 64, 16 }, { 35, 56, 97, 28 },{ 29, 10, 81, 12 } };
int max = 0;
int x = -1;
int y = -1;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] > max) {
max = array[i][j];
x = i + 1;
y = j + 1;
}
System.out.print(array[i][j] + "\t");
}
System.out.println();
}
System.out.println("该二维数组中最大值是:" + max);
System.out.println("位置是第" + x + "行,第" + y + "列");
}
}
【总结与提示】
- 数组里只能存储相同类型的数据;
- 数组的长度一旦创建便不能改变;
- 声明数组时,方括号“[]”既可以放在数据类型的后面,也可以放在数组名的后面;
- 数组的下标从0开始。