JAVA数组重点掌握知识,以后肯定会用到的,可以了解一下底层原理。数组是指一组数据的集合,数组中的每个数据被称作元素。在数组中可以存放任意类型的元素,但同一个数组里存放的元素类型必须一致。
数组
数组定义格式:
数据类型[] 数组名(变量名) = new 数据类型[元素个数或数组长度];
实例:
public class ArrayDemo01 {
public static void main(String[] args) {
int[] x = new int[100];
}
}
注意:数组定长,一但定义长度为100,在使用时大小就是100了。不变量。
数组特点:定长、引用类型。
JVM
java程序运行时,操作系统会给jvm虚拟机分配一块内存。JVM又会将这块内存,进行划分管理。
JVM内存划分:JVM对自己的内存进行了划分,分成5个区域。
1、寄存器:内存和CPU之间。
2、本地方法栈:JVM调用操作系统中的功能。
3、方法和数据共享:运行时其class文件,进入的地方。
4、方法栈:所有的方法运行的时候,进入的内存。
5、堆:存储的是容器和对象。
开发人员主要关心:方法和数据共享、方法栈、堆。
数组内存划分
- 首先,运行class文件,所以先进入方法区。
- 运行main方法,在方法栈中运行,但是main用不了那么多,所以方法栈中会分配一块给main方法是用。
- 执行数组,一个容器,所以JVM在堆内存,开空间,存储数组容器。
- JVM会将该地址,给定义的数组变量arr(相当于arr引用了这个地址),所以数组是引用类型。
- 每次运行,JVM分配的地址是不同的。
- 当main方法运行完了,arr变量就没了,然后new int[3]也就没了 ,JVM垃圾回收机制,会自动帮我们回收,不用我们去处理了。
堆空间太大,怎么找到这个容器呢,所以每个数组,在内存中,都有自己的内存地址,也就是数组元素的首地址,第一个数据的地址。
注意:arr引用类型,保存的数据,实际上是内存中的地址。
数组元素的访问
数组是一个容器,存储到数组中的每个元素,都有自己的自动编号/下标(专业名词:索引)。
访问数组存储的元素,必须依赖索引。
访问公式:数组名[索引]
public class ArrayDemo02 {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
一初始化时,数组里面就有了默认值。
注意:数组索引是从0开始的。当数组被成功创建后,数组中元素会被自动赋予一个默认值,根据元素类型的不同,默认初始化的值也是不一样的。
byte、short、int、long:默认值0
float、double:默认值0.0
char:默认值一个空字符(空格),即’\u0000’
boolean:默认值false
引用数据类型:null,表示变量不引用任何对象
数组的属性
数组的长度length:
使用方法:数组名.length
public class ArrayDemo02 {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr.length);
}
}
注意:length是int类型,因此数组最大索引为:数组名.length-1
数组中最小的索引是0,最大的索引是“数组的长度-1”。在Java中,为了方便我们获得数组的长度,提供了一个length属性,在程序中可以通过“数组名.length”的方式来获得数组的长
度,即元素的个数。
数组初始化
- 在定义数组时只指定数组的长度,由系统自动为元素赋初值的方式称作动态初始化。
数组的静态初始化
方式一:数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3...};
方式二:数据类型[] 变量名 = {元素1,元素2,元素3,...};
public class ArrayDemo03 { public static void main(String[] args) { //定义方式一 int[] arr = new int[] {1,3,4,5}; System.out.println(arr.length); //注意:new 后面的中括号中,不允许写任何内容,写了就编译失败。 //错误实例: //int[] arr = new int[4]{1,2,3,4}; //定义方式二(这种比较简单,常用) int[] arr2 = {1,2,3,4,}; //注意:最后一个逗号,会自动去掉 System.out.println(arr2.length); } }
注意:第3行代码千万不可写成int[] arr = new int[4]{1,2,3,4};,这样写编译器会报错。原因在于编译器会认为数组限定的元素个数[4]与实际存储的元素{1,2,3,4}个数有可能不一致,存在一定的安全隐患。
数组元素赋值
public class ArrayDemo04 {
public static void main(String[] args) {
//没有赋值的元素,都是默认值
int[] arr = new int[3];
arr[2] =5;
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
注意:如果在使用数组时,不想使用这些默认初始值,也可以显式地为这些元素赋值,如上代码。
数组的遍历
遍历:通过索引的方式,将数组中的每个元素,分别获取出来。
public class ArrayDemo05 {
public static void main(String[] args) {
int[] arr = {1,2,4,52,4,3,6,};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
//......
//如果有几千个,这样肯定不行,索引是依次加1的,因此可以用到循环来变量。
//for:知道循环次数,计数器思想
//while:不确定循环次数。
for(int i=0;i<arr.length;i++) {
System.out.println(arr[i]);
}
}
}
输出结果:
1
2
4
52
1
2
4
52
4
3
6
注意:
//for:知道循环次数,计数器思想
//while:不确定循环次数。
会自动去掉最后一个逗号。
数组中常见异常
数组索引越界异常
public class ArrayError { public static void main(String[] args) { int[] arr = {1,2,4,}; //1、数组索引越界异常 System.out.println(arr[3]); System.out.println(arr[-2]); } }
输出结果,编译时不出错,运行时,错误提示信息:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
错误原因:索引越界、索引为负数。
空指针异常
public class ArrayError { public static void main(String[] args) { //2、空指针异常 int[] arr2 = {2,345,4}; System.out.println(arr2[2]);; arr2 = null;//arr2不在保持数组的地址了 System.out.println(arr2[2]); } }
空指针内存运行说明:
步骤1:int[] arr2 = {1,5,8},存在于栈中 步骤2:同时在堆中开辟一块内存空间存储数据,并分配一个地址,如图右边。 步骤3:arr2变量,引用执行该存储空间地址。 上面3步是正常情况。 步骤4:当执行arr2=null时,arr2引用就没有了指向的空间地址。 步骤5:打印的数组的时候就会出现空指针异常了。
输出结果:错误提示信息
Exception in thread "main" java.lang.NullPointerException
错误原因:数组变量为null
注意:内存地址只能给一次,不能给第2次地址。因为为null空指向断了,JVM可能已经将堆地址内存释放掉了,不能再给回来。
数组获取最值
获取最值的原理思想:找到数组中的最大值或最小值,然后做比较。
最大值或最小值比较思想:将最大值放到一个变量中,赋值为第一个元素,每次将这个值与其他元素比较,将大的给这个值,最后这个就是最大值。最小值同理。
public class ArrayDemo05 {
public static void main(String[] args) {
int[] arr = { 4, 1, 6, 3, 9, 8 }; // 定义一个数组
int max = arr[0]; // 定义变量max用于记住最大数,首先假设第一个元素为最大值
// 下面通过一个for循环遍历数组中的元素
for (int x = 1; x < arr.length; x++) {
if (arr[x] > max) { // 比较 arr[x]的值是否大于max
max = arr[x]; // 条件成立,将arr[x]的值赋给max
}
}
System.out.println("max=" + max); // 打印最大值
}
}
说明:
1、定义了一个临时变量max,用于记住数组的最大值。通过for 循环获取数组中的最大值,赋值给max变量。
2、首先假设数组中第一个元素arr[0]为最大值。
3、使用for循环对数组进行遍历,在遍历的过程中只要遇到比max值还大的元素,就将该元素赋值给max。
4、这样一来,变量max就能够在循环结束时记住数组中的最大值。
需要注意的是,在for循环中的变量i是从1开始的,这样写的原因是程序已经假设第一个元素为最大值,for循环中只需要从第二个元素开始比较,从而提高程序的运行效率。
二维数组
二维数组的定义有很多方式,几种常见的方式。
第一种方式:
int[][] arr = new int[3][4];
上面的代码相当于定义了一个3*4的二维数组,即二维数组的长度为3,二维数组中的每个元素又是一个长度为4的数组,接下来通过一个图来表示这种情况,如下图所示。
第二种方式:
int[][] arr = new int[3][];
第二种方式和第一种类似,只是数组中每个元素的长度不确定.
第三种方式:
int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
上面的二维数组中定义了三个元素,这三个元素都是数组,分别为{1,2}、{3,4,5,6}、{7,8,9}。
对二维数组中元素的访问也是通过角标的方式,如需访问二维数组中第一个元素数组的第二个元素,具体代码如下:
arr[0][1];
操作二维数组时,经常需要获取数组中元素的值。
public class TwoArrayDemo {
public static void main(String[] args) {
//二维数组创建方式
//方式一
int[][] arr = new int[2][3];
//方式二
int[][] arr2 = new int[2][];
arr2[0] = new int[5];
arr2[1] = new int[1];
//方式三
int[][] arr3 = {{2,4,5},{1,2},{6,3,5,5}};
//这种方式最简单,最常用。
}
}
二维数组内存分配:
public class TwoArrayDemo {
public static void main(String[] args) {
int[][] arr3 = {{2,4,5},{1,2},{6,3,5,5}};
//二维数组的访问
System.out.println(arr3[2][2]);
//二维数组的遍历
for(int i=0;i<arr3.length;i++) {
for(int j=0;j<arr3[i].length;j++) {
System.out.print(arr3[i][j]);
}
System.out.println();
}
}
}
评论 (0)