一、数组的基本用法
1.什么是数组
数组本质上就是让我们能”批量“创建相同类型的变量
例如:
2.创建数组
基本语法
代码示例:
int [] arr=new int[]{1,2,3};//创建一个整型数组,并赋值1,2,3
int [] arr={1,2,3};
3.数组的使用
代码示例:
public static void main(String[] args) {
int[] array = new int[]{1, 2, 3};
int a = array.length;//获取数组长度;
int b=array[0];//获取数组的第一个元素
int c=array[1];//获取数组的第二个元素
int d=array[2];//获取数组的第三个元素
System.out.println(a+" "+b+" "+c+" "+d+" ");
}
//运行结果
3 1 2 3
总结:
1.使用array.length能够获取到数组的长度
2.使用[ ] 按下标获取元素数组,需要注意的是下标是从0开始,不是从1开始;
3.使用 [ ]既能获取数据,也能修改数据
4.下标不能超出有效范围[0,length-1],如果超出有效范围,就会出现下标异常。
补充:
为什么下标要从0开始?
代码示例:遍历数组
所谓遍历,是指将数组中的所有元素都访问一遍,通常需要搭配循环语句。
public static void main(String[] args) {
int[] array = new int[]{1, 2, 3};
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
//运行结果
1
2
3
这里是直接打印了元素组的元素
增强型 for-each语句遍历数组
public static void main(String[] args) {
int[] array = new int[]{1, 2, 3};
for (int x : array) {
System.out.print(x+" ");
}
}
这里x是将原数组的元素复制只有赋值给了x,然后打印x的值,并不是打印的原数组的元素。
二、数组作为方法的参数
2.1.基本用法
前面我们学习了方法,他可以增加代码的复用性,简化主方法,使用时调用就行。
那么在构造方法时,使用数组作为形参该怎么用呢
代码示例:打印数组内容
public static void main(String[] args) {
int[] array = new int[]{1, 2, 3};
print(array);
}
public static void print(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
运行结果
1 2 3
在这个代码中,实参时int[ ] array ,形参时int[ ] arr;
2.2.理解引用数据类型
代码示例1:
public static void main(String[] args) {
int a = 10;
int b = 20;
transform(a,b);
System.out.println(a + " " + b);
}//运行结果 10 20;
public static void transform(int a, int b) {
int temp = a;
a = b;
b = temp;
}
我们发现我们在方法中交换了形参的值,但是实参的值却没有变化。
代码示例2:
public static void main(String[] args) {
int[] a={1,2};
transform(a);
System.out.println(a[0]+" "+a[1]);
}//运行结果 2 1
public static void transform(int[] array) {
int temp=array[0];
array[0]=array[1];
array[1]=temp;
}
这里我们交换形参数组两个元素的值,发现实参数组的元素值也发生变化了。
此时数组名a是一个引用,当传参的时候,是按照引用传参。
为什么会出现这种情况呢??
我们知道计算机一切的计算都是在内存中进行的。那么出现这种情况,一定和内存有关。
什么是内存呢?
内存就是我们常说的,计算机内存是16+512中的16,内存我们可以理解为在一个宿舍楼,长长的走廊上有许许多多的房间,每个房间的大小是一个byte,每个房间都有一个门牌号,这个门牌号就是地址。
什么是引用呢?
引用相当于一个别名,也可以理解成指针,
创建一个引用只是相当于创建了一个很小的变量,就是上文提到的int[ ]变量,保存了内存中的一个地址。
此时已经将 0x100 地址的数据改成了 100 . 那么根据实参 arr 来获取数组内容 arr[0] , 本质上也是获取 0x100
地址上的数据, 也是 100.
总结:
2.3.初识JVM内存区域划分
JVM 的内存被划分成了几个区域, 如图所示:
想知道上面为什么会出现那种情况,我们只需要了解虚拟机栈和堆:
那么具体看看上面两个示例在内存中的操作流程
三、数组作为返回值
代码示例: 写一个方法, 将数组中的每个元素都 * 2
//直接更改原数组
class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
transform(arr);
printArray(arr);
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void transform(int[] arr) {
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
}
}
}
这个代码固然可行, 但是破坏了原有数组. 有时候我们不希望破坏原数组, 就需要在方法内部创建一个新的数组, 并由方法返回出来.
// 返回一个新的数组
class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int[] output = transform(arr);
printArray(output);
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static int[] transform(int[] arr) {
int[] ret = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ret[i] = arr[i] * 2;
}
return ret;
}
}
这样的话就不会破坏原有数组了.
另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比较高效.