一、数组的定义
1、 数组
可以看成相同数据类型的集合,且在内存中是一段连续的空间,下标从0开始。
2、 数组的创建
int[] 数组名 = new int[10];
其中,int 可以换成其他数据类型,不仅仅是八大基本数据类型,10也可以换成其他数。
3、 数组的初始化
主要分为动态初始化和静态初始化。
(1)、动态初始化 : 在创建数组时,直接指定数组中元素的个数。
int[] array1 = new int[4];
(2)、静态初始化 : 在创建数组时不直接给定数据的元素个数,而是直接将数据的具体内容进行指定。 (还是以int型数组举例,这里可以时任何类型)
int[] array2 = new int[]{1,2,3,4,5}; // 这里的 new int[] 可以不写。
int[] array2 = {1,2,3,4,5};
String[] array3 = {"Hello","Hi","Wow"};
注意 :
- 静态初始化没有指定数组长度,但编译器会在编译时根据{ }中的元素个数来确定数组的长度。
- { } 里的数据类型必须和 【】前的数据类型一样。
- 也可以和C语言一样创建数组,但是Java里不推荐,很容易造成数组就是 int型的误解。
int array[] = {1,2,3}; // 对,但不推荐!
- 可以拆分定义,但是省略的 new int[ ] 不可以忽略。
int[] array1;
array1 = new int[12];
int[] array2;
array2 = new int[]{1,2,3,4};
- 如果没有对数组初始化,如果数组类型是基本数据类型,则根据基本类型对应的默认值。
- 若为引用类型,则默认为null。
4、 数组的使用
(1)数组中的元素访问
int[] array1 = new int[10];
int[] array2 = {1,2,4,5,6};
System.out.println(array1[4]); // 0
System.out.println(array2[3]); // 5
array1[4] = 12;
System.out.println(array1[4]); // 12 可以修改数中的元素。
array2[3] = 7;
System.out.println(array2[3]); // 7
- 因为数组是一段连续的内存空间,因此可以支持随机访问,可以通过下标访问快速访问任意数组中任意位置的元素—数组下标从0开始,下标即偏移量,即每个元素离首元素的距离,比如首元素离自己本身偏移量为0,所以下标为0,第三个离首字母为2(首字母,第二个,第三个)所以下标为2,所以下标为第几个 n-1 就行。
- 不能越界–访问数组时 数组名称(下标),注意一旦超过元素数量会发生越界异常。
(2)遍历数组
遍历 :是指将数组中的每一个元素都访问一次,访问是指对每一个元素进行某种操作。
int[] array1 = {1,10,100,1000,10000};
for (int i = 0; i < 5 ; i++) {
System.out.println(array1[i]);
(3) 获取数组长度
用数组对象.length 来获取数组长度。
遍历数组:
int[] array1 = {1,10,100,1000,10000,100000,1000000};
for (int i = 0; i < array1.length ; i++) {
System.out.println(array1[i]);
public static void main(String[] args) {
int[] array01 = {1,2,3,4,5};
System.out.println(array01.length);
for (int i = 0; i < array01.length; i++) {
System.out.print(array01[i]);
if (i < array01.length - 1){ // 只有当元素i之后还有元素才打印"、";
System.out.print("、");
}
}
}
for-each 遍历数组
int[] array1 = {1,2,3,4};
for (int x : array1) {
System.out.println(x);
for-each 是 for 循环的另外一种使用方式. 能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错.------此时的 int x 就是一个局部变量,依次将数组中的每一个元素赋值给 i ,这个循环无法修改数组的元素。
二、数组是引用类型
1、初始JVM的内存分布
内存是一段连续的存储空间 ,主要是用来存储程序运行时的数据。
堆 : JVM所管理的最大内存区域,使用new创建的对象都是在堆中保存的,堆是随着程序的开始而创建,随着程序的退出而销毁,堆中的数据只要还在使用,就不会被销毁。
栈 : 每个方法执行时,都会先创建一个栈帧,当方法运行结束后,栈帧就被销毁了 ,即栈帧中保存的数据也销毁了。
现在只考虑栈和堆,其他的后面在学习。
2、 基本类型变量和引用类型变量的区别
基本类型变量 : 简称基本变量,该变量空间中存放的是其所对应的值;
引用数据类型创建的变量 : 一般为对象的引用,其空间存储的是其对象所在空间的地址。
int a = 10;
int b = 12;
int[] array = new int[]{1,2,3};
其中,a 和 b 都是基本变量,因此其空间中存放的就是a和b的值;
array 是数组类型的引用变量,其空间中存放的是 数组在堆空间中的首地址。
- 参数传基本数据类型
public class ArrayTest {
public static void main(String[] args) {
int num = 0;
func(num);
System.out.println("num=" + num);
}
public static void func(int x) {
x = 10;
System.out.println("x=" + x);
}
} // x = 10 num = 0
发现在修改函数内部形参X的值,不影响实参num的值;
- 参数传递数组类型(引用类型)
public class ArrayTest {
public static void main(String[] args) {
int[] array = {1,2,3};
func(array);
System.out.println("array[0]=" + array[0]);
}
public static void func(int[] i) {
i[0] = 10;
System.out.println("i[0]=" + i[0] );
}
} // i[0] = 10 array[0] = 10;
因为数组是引用类型的,所以参数传递类型为引用时,修改形参可以改变实参。
- 数组作为函数的返回值,以fib数为例子:
public class fibonacci {
public static void main(String[] args) {
int[] res = fib(5);
for (int i = 0; i < res.length; i++) {
System.out.print(res[i]);
if (i < res.length - 1){
System.out.print("、");
}
}
}
public static int[] fib(int num){
int[] fib = new int[num];
fib[0] = fib[1] = 1;
for (int i = 2; i < fib.length; i++) { // i 是数组下标;
fib[i] = fib[i-1] + fib[i-2];
}
return fib;
}
}