内容简介:JavaSE基础:数组
-
数组是 相同数据类型 的 有序 集合
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成.其中,每个数据称作一个数组的元素,每个数组元素可以通过一个索引(或者下标)来访问它们.
-
数组的三个特点:
- 数组的长度是确定的. 数组当被创建时,它的大小就是不可以改变的.
- 数组元素必须是相同类型,不允许出现混合类型
- 数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型
2.一维数组
(1) 声明方式
-
方式一
数据类型 数组名[] = null ; //声明一维数组 数组名 = new 数组类型[长度]; // 分配内存给数组
-
方式二
数据类型[] 数组名 = null ; //声明一维数组 数组名 = new 数组类型[长度]; // 分配内存给数组
-
简写方式
数据类型 数组名[] = new 数据类型[个数]; //声明数组的同时分配内存
(2) 数组中元素的表示方法
-
数组的声明以及简单输出
package com.shxt.demo01; public class ArrayDemo01 { public static void main(String[] args) { int[] score = null; //声明数组,但是为开辟内存空间 score = new int[3]; //为数组开辟"堆内存"空间 System.out.println("score[0]="+score[0]); //分别输出数组的每个元素 System.out.println("score[1]="+score[1]); //分别输出数组的每个元素 System.out.println("score[2]="+score[2]); //分别输出数组的每个元素 // 使用循环依次输出数组中的全部内容 for (int i = 0; i < 3; i++) { System.out.println("score["+i+"]="+score[i]); } } }
对于数组的访问采用"数组名称[索引或者下标]"的方式,索引从0开始计数,假设程序中取出的内容超过了这个下标范围,例如:
score[3]
程序运行会存在以下的异常错误提示信息:java.lang.ArrayIndexOutOfBoundsException:3
提示的内容为数组索引超出绑定的异常(经常说的数组越界异常),这个是未来你们初学者经常出现的问题,请引起重视.此外,我们发现以上的程序运行的结果的内容都是"0",这是因为声明的数组是整型数组.
默认初始化数据:数组元素相当于对象的成员变量,默认值跟成员的规则是一样的,重点记忆!
系统将按照如下规则分配初识值:
- 数组元素的类型是基本类型中的整数类型(byte,short,int和long),则数组元素的值为0
- 数组元素的类型是基本类型中的浮点类型(float,double),则数组元素的值为0.0
- 数组元素的类型是基本类型中的字符类型(char),则数组元素的值为'\u0000'(空格)
- 数组元素的类型是基本类型中的布尔类型(boolean),则数组元素的值为false
- 数组元素的类型是引用数据类型(类,接口和数组),则数组元素的值为null
-
为数组中的元素赋值并进行输出
声明整型数组,长度为5,通过for循环赋值1,3,5,7,9的数据
package com.shxt.demo01; public class ArrayDemo02 { public static void main(String[] args) { int[] score = null; //声明数组,但是为开辟内存空间 score = new int[5]; //为数组开辟"堆内存"空间 for (int i = 0; i < 5; i++) { score[i] = i*2+1; } for (int i = 0; i < 5; i++) { System.out.println("score["+i+"]="+score[i]); } } }
-
数组长度的取得
数组名称.length --> 返回一个int型的数据
package com.shxt.demo01; public class ArrayDemo03 { public static void main(String[] args) { int[] score = new int[5]; System.out.println("数组长度为:"+score.length); } }
(3) 数组的初始化方式
-
动态初始化
之前练习的就是使用的动态初始化方式
package com.shxt.demo01; public class ArrayDemo04 { public static void main(String[] args) { int[] score = null; //声明数组,但是为开辟内存空间 score = new int[3]; //为数组开辟"堆内存"空间 score[0] = 100; score[1] = 200; score[2] = 300; } }
-
静态初始化
数据类型[] 数组名={初始值0,初始值1,...,初始值N} 或者 数据类型[] 数组名 = new 数据类型[]{初始值0,初始值1,...,初始值N}
package com.shxt.demo01; public class ArrayDemo04 { public static void main(String[] args) { int[] score = {10,20,30,40,50}; for (int i = 0; i < score.length; i++) { System.out.println("score["+i+"]="+score[i]); } } }
(4) 课堂练习
-
已知一个字符数组
char[] letterArray = new char[26]
,请动态初始化数据为A~Zpackage com.shxt.demo01; public class ArrayDemo05 { public static void main(String[] args) { char[] letterArray = new char[26]; for (int i = 0; i < letterArray.length; i++) { letterArray[i] = (char)('A'+i); } for (int i = 0; i < letterArray.length; i++) { System.out.print(letterArray[i]+"\t"); } } }
-
请求数组中最大和最小值
package com.shxt.demo01; public class ArrayDemo06 { public static void main(String[] args) { int array[]={74,12,48,888,30,5,17,62,777,666}; int max = array[0]; int min = array[0]; for (int i = 0; i < array.length; i++) { if(array[i]>max){ max=array[i]; } if(array[i]<min){ min=array[i]; } } System.out.println("最高成绩:"+max); System.out.println("最低成绩:"+min); } }
-
对整数数组按照由小到大的顺序进行排序
public class ArrayDemo07 { public static void main(String[] args) { int arr[] = {13,34,57,78,99,66,43,45,87,100}; for (int i = 0 ; i < arr.length; i++) { for (int j = 0; j < arr.length-1; j++) { if(arr[j]>arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } System.out.print("第"+i+"次 排序 的结果:\t"); for (int k = 0; k < arr.length; k++) { System.out.print(arr[k]+"\t"); } System.out.println(); } System.out.print("最终的排序结果:\t"); for (int k = 0; k < arr.length; k++) { System.out.print(arr[k]+"\t"); } } }
排序自学参考资料: http://geek.csdn.net/news/detail/113928
(5) 数组的问题
-
数组一定要初始化吗?
在之前我们说在使用 Java 数组之前必须要先初始化数组( 即在使用数组之前,必须先创建数组 ).实际上,如果真正掌握了Java数组中的分配机制,那么可以完全换一个方式来初始化数组.
始终记住: Java的数组变量只是 引用类型 的变量,它并不是数组对象本身,只是让数组变量 指向 有效的数组对象,程序中即可使用该数组变量
package com.shxt.demo01; public class ArrayDemo08 { public static void main(String[] args) { // 静态初始化:定义并且初始化nums数组 int nums[] = {13,34,57,100}; // 定义一个scores数组变量 int[] scores; //让scores数组执行nums所引用的数组 scores = nums ; // 对scores进行变量 System.out.print("scores数组数据:"); for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+"\t"); } // 将scores数组中第3个元素赋值为200 scores[2] = 200; // 访问 nums 数组的第3个元素,将看到输出值为200 System.out.println("\nnums 数组的第3个元素,将看到输出值为:"+nums[2]); } }
既然数组内容可以进行引用传递,那么就可以把数组作为方法中的参数,而如果一个方法想接收参数,则对应的参数类型必须是数组
-
使用方法接收数组
package com.shxt.demo01; public class ArrayDemo09 { public static void main(String[] args) { // 静态初始化:定义并且初始化nums数组 int nums[] = {13,34,57,100}; // 引用传递, int[] temp = nums print(nums); } public static void print(int[] temp){ for (int i = 0; i < temp.length; i++) { System.out.print(temp[i]+"\t"); } } }
-
使用方法修改数组的内容
package com.shxt.demo01; public class ArrayDemo10 { public static void main(String[] args) { // 静态初始化:定义并且初始化nums数组 int nums[] = {1,2,3,4,5}; // 引用传递, int[] temp = nums inc(nums); //扩容操作 print(nums); //打印内容 } public static void inc(int[] temp){ for (int i = 0; i < temp.length; i++) { temp[i]*=2; } } public static void print(int[] temp){ for (int i = 0; i < temp.length; i++) { System.out.print(temp[i]+"\t"); } } }
3.二维数组
之前定义的数组只有一个"[]",表示一维数组,如果有两个"[]"就是二维数组,其实本质上不存在多维数组的概念,其实就是一维数组中有嵌套了数组而已
-
一维数组表格表示
索引 0 1 2 3 4 5 数据 10 20 30 40 50 60
-
二维数组表格表示
int[3][6]
索引 0 1 2 3 4 5 0 3 4 5 6 7 8 1 10 20 30 50 40 60 2 111 222 333 444 555 666 -
二维数组的定义
-
动态初始化
数据类型[][] 数组名 = new 数据类型[行数][列数];
-
静态初始化
数据类型[][] 数组名 = new 数据类型[[]{{值1,值2},{值1,值2,值3...},{值1...}};
-
-
遍历二维数组
package com.shxt.demo01; public class ArrayDemo11 { public static void main(String[] args) { int[][] data = new int[][]{{1,2,3},{10},{100,200}}; for (int i = 0; i < data.length; i++) { //循环行数 for (int j = 0; j < data[i].length; j++) { //循环列数 System.out.print(data[i][j]+"\t"); } System.out.println(); } } }
4.Java新特性对数组的支持
(1) 可变参数
在调用一个方式,必须根据方法的定义传递指定的参数,但是在JDK1.5之后产生了新的概念--可变参数(即方法中可以接收的参数不再是固定的,而是随着需要传递的)
a.可变参数的定义格式
返回值类型 方法名称(数据类型... 参数名称)
方法中传递可变参数之后, 实际上参数是以 数组 的形式保存下来的,关键点
b.使用可变参数定义的方法
package com.shxt.demo02; public class TestVarArgus { public static void main(String[] args) { System.out.println("不传递参数 fun():"); fun(); //不传递参数 System.out.println("传递1个参数 fun(100) :"); fun(100); //传递一个参数 System.out.println("\n传递2个参数 fun(10,20,30,40,50) :"); fun(10,20,30,40,50); //传递5个参数 } public static void fun(int... params){ //可变参数可以接收任意多个参数 for (int i = 0; i < params.length; i++) { System.out.print(params[i]+"\t"); // 实际上参数是以 数组 的形式保存下来的 } } }
代码分析:
通过main方法里的调用,可以看出来这个可变参数既可以是没有参数(空参数),也可以是不定长的。看到这里估计都能明白,这个不定长的参数其实和数组参数挺像的。事实上,也确实是这么回事儿。编译器会在悄悄地把这最后一个形参转化为一个数组形参,并在编译出的class文件里作上一个记号,表明这是个实参个数可变的方法。请看代码:
fun();//fun(int[] intArray{}); fun(100);//fun(int[] intArray{100}); fun(10,20,30,40,50);//fun(int[] intArray{10,20,30,40,50});
c.发现问题
问题1:看看是不是这个可变参数就是数组类参数?
问题2:可变参数能否接收数组呢?
package com.shxt.demo02; public class TestVarArgus { public static void main(String[] args) { int[] intArray = { 1, 2, 3 }; fun(intArray); //传递数组,编译通过,正常运行 } public static void fun(int... params){ //可变参数可以接收任意多个参数 for (int i = 0; i < params.length; i++) { System.out.print(params[i]+"\t"); } } }
错误的示例代码
代码分析:
通过这两端代码可以看出来,[重点知识]可变参数是兼容数组类参数的,但是数组类参数却无法兼容可变参数!
问题3:可变参数可以放置在形参中的任意位置吗?
代码分析:
可变参数类型必须作为参数列表的最后一项,而不能放在定长参数的前面。
问题4:重载方法的优先级问题?
package com.shxt.demo02; public class TestVarArgus { public static void fun(int... intArray) { System.out.println("11111"); } public static void fun(int num1 , int num2) { System.out.println("22222"); } public static void main(String args[]) { fun(100,200); } }
代码分析:
控制台的数据结果为: 22222
这里需要记住: 能匹配定长的方法,那么优先匹配该方法。含有不定参数的那个重载方法是最后被选中的 。
留在最后的一句话: main方法的参数就是一个数组类型的,那么它其实也是可以改成不定参数类型
d.可变参数的总结
- 只能出现在参数列表的最后;
- ... 位于变量类型和变量名之间,前后有无空格都可以;
- 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
- 如果一个是两个方法是重载,一个是可变参数,一个是固定参数,然后我们调用方法如果故常长度的能满足,那么有优先调用固定长度的,
###(2) foreach输出
数组的输出一遍都会使用for循环,但是在JDK1.5后为了方便数组的输出,提供了foreach的语法,格式如下
for(数据类型 变量名称 : 数组名称){ //代码主体 }
简单示例代码
package com.shxt.demo02; public class TestVarArgus { public static void main(String[] args) { System.out.println("不传递参数 fun():"); fun(); //不传递参数 System.out.println("传递1个参数 fun(100) :"); fun(100); //传递一个参数 System.out.println("\n传递2个参数 fun(10,20,30,40,50) :"); fun(10,20,30,40,50); //传递5个参数 } public static void fun(int... params){ //可变参数可以接收任意多个参数 for (int num : params) { System.out.print(num+"\t"); } } }
扩展说明:
可以反编译class文件,我们会看到增强(加强)for循环的语法结构为:
public static void fun(int... params) { int[] var1 = params; int var2 = params.length; for(int var3 = 0; var3 < var2; ++var3) { int num = var1[var3]; System.out.print(num + "\t"); } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
What Technology Wants
Kevin Kelly / Penguin Group (USA) Incorporated / 2010-10-14 / USD 27.95
A refreshing view of technology as a living force in the world. This provocative book introduces a brand-new view of technology. It suggests that technology as a whole is not a jumble of wires and ......一起来看看 《What Technology Wants》 这本书的介绍吧!