数组的定义与使用
数组的基本用法
1. 什么是数组
数组本质上就是让我们能 “批量” 创建相同类型的变量. 例如:
如果需要表示两个数据, 那么直接创建两个变量即可 int a; int b
如果需要表示五个数据, 那么可以创建五个变量
int a1; int a2; int a3; int a4; int a5;
但是如果需要表示一万个数据, 那么就不能创建一万个变量了.
这时候就需要使用数组, 帮我们批量创建.
注意事项: 在 Java 中, 数组中包含的变量必须是 相同类型.
2. 创建数组
基本语法
// 动态初始化
数据类型[] 数组名称 = new 数据类型 [长度] { 初始化数据 };
// 静态初始化
数据类型[] 数组名称 = { 初始化数据 };
代码示例
注意事项: 静态初始化的时候, 数组元素个数和初始化数据的格式是一致的.
int[] arr = new int[3]{1, 2, 3};
int[] arr = {1, 2, 3};
3.数组的使用
代码示例
//2.数组的使用:获取数组长度和访问数组元素
public class TestArr {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
System.out.println(arr[0]);//输出1
int length = arr.length;//获取数组长度
System.out.println(length);//输出5
}
}
注意事项:
- 使用 arr.length 能够获取到数组的长度. . 这个操作为成员访问操作符. 后面在面向对象中会经常用到.
- 使用 [ ] 按下标取数组元素. 需要注意, 下标从 0 开始计数
- 使用 [ ] 操作既能读取数据, 也能修改数据.
- 下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常
遍历数组的两种方式:
1.for循环遍历数组
2.for-each遍历数组(类似与C++中的范围for)
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
//1.for循环遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println();
//2.for-each遍历数组
for(int e : arr) {
System.out.print(e);
}
System.out.println();
}
4.数组作为方法的参数
用方法打印数组中的内容
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
//1.打印数组中的内容,printArray
printArray(arr);
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println();
}
理解引用的类型(重点)
代码示例1 参数传内置类型
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的值并未改变num的值,其实这个很好理解,就是num和x指向的是两个不同的地址空间,二者不相互影响
代码示例2 参数传数组类型
public static void main(String[] args) {
int[] arr = {1,2,3};
func(arr);
System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a) {
a[0] = 10;
System.out.println("a[0] = " + a[0]);
}
我们发现, 在函数内部修改数组内容, 函数外部也发生改变. 此时数组名 arr 是一个 “引用” . 当传参的时候, 是按照引用传参.
这里我们要先从内存开始说起.
如何理解内存?
内存就是指我们熟悉的 “内存”. 内存可以直观的理解成一个宿舍楼. 有一个长长的大走廊, 上面有很多房间. 每个房间的大小是 1 Byte
(如果计算机有 8G 内存, 则相当于有 80亿 个这样的房间).
每个房间上面又有一个门牌号, 这个门牌号就称为 地址
那么啥又是引用? 什么是引用?
引用相当于一个 “别名”, 也可以理解成一个指针.
创建一个引用只是相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址. 针对 int[] arr = new int[]{1, 2, 3}
a) 当我们创建 new int[]{1, 2, 3}
的时候, 相当于创建了一块内存空间保存三个 int
b) 接下来执行 int[] arr = new int[]{1, 2, 3}
相当于又创建了一个 int[] 变量, 这个变量是一个引用类型, 里 面只保存了一个整数(数组的起始内存地址)
总结: 所谓的 “引用” 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实只 是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大).
5.数组作为方法的返回值
写一个方法将数组的每个元素*2,但不改变原数组的值
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
//写一个方法将数组中的每个元素乘2,但不改变原数组的值
String str1 = arr2Str(arr);
System.out.println(str1);
int[] newArr = transform(arr);
String str2 = arr2Str(newArr);
System.out.println(str2);
}
public static int[] transform(int[] arr) {
int[] newArr = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i] * 2;
}
return newArr;
}
//将数组转换为字符串
public static String arr2Str(int[] arr) {
String str = "[";
for (int i = 0; i < arr.length; i++) {
str += arr[i];
if(i == arr.length - 1) {
str += "]";
}else {
str += ", ";
}
}
return str;
}
执行结果: