1.遍历(接上篇)
我们为什么要遍历数组而不是直接打印数组呢?
我们来一看一下直接打印数组会发生什么
直接打印得到的并不能得到遍历的效果,而是一串奇怪的编号,我们来一起了解它的组成
如果我们将后面当做一个地址,那么它存储的是数组首元素的地址。
注意:数组存储的是地址,而不是直接将数据存储在数组中,因此,数组不是基本数据类型,而是引用数据类型。
除了运用之前我们学过的for循环、while循环等,Java自己提供了遍历数组的方法。
运用Arrays方法,注意运用这个的时需要导包,类似于C语言中的导包 #include,还有返回值,为String类型,演示如下
根据运行的结果我们可以发现,还打印了数组的括号,说明这个遍历方法是将指定数组以字符串的形式输出的。
2. JVM
如图所示,JVM的组成
- Java虚拟机栈:存储局部变量。
- 堆:存储的是对象,所以相对于Java虚拟机栈,堆的内存更大。
- 本地方法栈:保存的内容是Native方法的局部变量。
- 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
- 程序计数器:存储下一条指令。
所以我们可以画出数组在JVM中的内存布局
3.null
当我们在数组初始化时,给数组赋值null时,我们此时获取数组的长度会出现什么呢?
我们可以翻译为空指针异常,虽然Java中没有指针这个概念。
在这里的null是指,array这个引用没有指向任何对象,所以没有办法获取对象的长度。
4.数组的应用
数组作为函数参数分为两种
- 参数作为基本数据类型
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;)
}
我们可以发现,当参数为基本数据类型时,func方法中修改形参x的值,不影响实参num的值。
- 参数传引用数据类型
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
func(arr);
System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] array){
array[0] = 0;
System.out.println("array[0] = " + array[0]);
}
我们可以发现,当参数传的是引用数据类型时,在func方法中修改数组的内容,main函数中的数组内容也发生变化。
懵了
5. 数组相关习题
5.1 数组转字符串
在Java中提供了许多包,其中 java.util.Arrays 中提供了一些常用的方法,例如将数组转化为字符串。
import java.util.Arrays;
public class test1 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
String s = Arrays.toString(arr);
System.out.println(s);
}
}
注意使用时需要导包,但是IDEA中会自动导入。
我们也可以自己实现 一个将数组转为字符串的方法,例如
注意:
当数组为空时和数组中没有值时的情况,两个情况不同,数组为空是数组不指向任何对象,而数组中没有值时是数组的长度为0。
5.2 数组的拷贝
public static void func(){
int[] arr = {1,2,3,4,5};
int[] array = arr;
array[0] = 0;
System.out.println("array:" + Arrays.toString(array));
}
当我们画出func方法在JVM中的内存布局,就会一目了然为什么arr[0]的值被改了
数组arr和数组array引用的是同一个数组,所以修改array时,arr也会改变。
什么时候手能不抖,我都服啦!
- Java有提供拷贝数组的方法,如图所示
通过这张图我们可以知道该方法的参数有两个,一个是要拷贝的数组,另一个是拷贝的长度,根据拷贝的长度,我们还可以对新数组进行扩容,即将拷贝的长度乘2或者乘3,根据要扩容的倍数来填写。
还有拷贝数组的某个范围
范围是左闭右边开,即下标1,2
根据上述 拷贝的方法我们来看以下代码的结果arr[0] 没有改变,array[0] 改变了
让我们来画func方法在JVM中的内存布局
死手,画快一点啊!
5.3 顺序查找
public static int find(int[] arr,int num){
for(int i = 0;i < arr.length;i++){
if(arr[i] == num) {
return i;
}
}
return -1;
}
5.4 二分查找
注意,使用二分查找时数组需要有序。
自己实现的代码如下
public static int binarySearch(int[] arr,int key) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] > key) {
right = mid - 1;
} else if (arr[mid] < key) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
5.5 冒泡排序
public static void bubbleSort(int[] arr){
for(int i = 0; i < arr.length - 1;i++){
for(int j = 0; j < arr.length - i - 1;j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
5.6 数组的逆序
public static void reverse(int[] arr){
int left = 0;
int right = arr.length - 1;
while(left < right){
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}