目录
数组的基本用法
数组的定义
数组的定义就是能够让我能“批量”的创建相同类型的变量。
注意:当你创建一个数组时,必须要知道数组的长度(即数组的数据的数目)。
数组的创建
动态初始化:
数据类型[ ] 数组名称 = new 数据类型[ ] {初始化数据};
静态初始化:
数据类型[ ] 数组名称 = {初始化数据};
键盘输入型数组创建:
//调用Scanner类
Scanner input = new Scanner(System.in);
//定义一个int型变量n来表示数组的变量个数(长度)
int n = input.nextInt();
//定义一个数组
int [] array = new int[n];
//定义一个for循环来输入数组的内容
for(int i = 0;i < array.length;i++) {
//数组的第一位数字的位数是从0开始的
//所以数组的长度array.length等于n
//调用Scanner类来输入数组的内容
array[i] = input.nextInt();
}
输入数组的全部代码:
//Arrays是java.util包下的类,它是操作数组的工具类
import java.util.Arrays;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//调用Scanner类
Scanner input = new Scanner(System.in);
System.out.print("请输入数组的变量个数:");
//定义一个int型变量n来表示数组的变量个数(长度)
int n = input.nextInt();
System.out.print("请输入数组的" + n + "个变量:");
//定义一个数组
int [] array = new int[n];
//定义一个for循环来输入数组的内容
for(int i = 0;i < array.length;i++) {
//数组的第一位数字的位数是从0开始的
//所以数组的长度array.length等于n
//调用Scanner类来输入数组的内容
array[i] = input.nextInt();
}
//打印数组的array地址
System.out.println(array);
//调用Array类下的toString方法来打印数组array的内容
System.out.println(Arrays.toString(array));
}
}
结果:
请输入数组的变量个数:6
请输入数组的6个变量:3 4 5 6 7 8
//这是数组在堆上开辟内存用来存储数组内容的地址
//System.out.println(array);
[I@7ea987ac
//打印数组的内容
// System.out.println(Arrays.toString(array));
[3, 4, 5, 6, 7, 8]
遍历数组
遍历数组就是把数组的内容打印(输出)到界面中。
for循环
public class Array {
public static void main(String[] args) {
//创建一个int型数组arr并初始化
int[] arr = {1,2,3};
//for循环来输出数组arr的每个元素
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
}
}
结果:
1
2
3
for-each(增强for循环)
public class Array {
public static void main(String[] args) {
int[] arr = {1,2,3};
//for-each输出数组arr的每个元素
for(int x : arr){
System.out.println(x);
}
}
}
结果:
1
2
3
调用java.util.Arrays类
import java.util.Arrays;
public class Array {
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(Arrays.toString(arr));
}
}
结果:
[1, 2, 3]
引用类型
引用的定义
引用相当于一个“别名”,也可以理解为一个指针。创建一个引用只是相当于创建了一个很小的变量,这个变量保存了一个整数,这个整数表示内存的一个地址。
内存就相当于上学住宿是的宿舍楼,每开辟一个内存就想当于占用了一个宿舍,每个宿舍有一个门牌号,这个门牌号就想当于地址。调用了这个引用类型就是调用了引用类型所指向的内存中的对象。
参数传内置类型
public class Array {
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 Array {
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[] arr){
arr [0] = 99;
System.out.println("arr[0] = " + arr[0]);
}
}
结果:
arr[0] = 99
array[0] = 99
在函数内部修改数组的值,函数外部也发生改变。
针对int [ ] array = new int [ ] {1,2,3};这类代码:
(1)当我们创建一个new int [ ] {1,2,3}相当于开辟一块内存存储了三个int型数据。
(2)在执行int [ ] array = new int [ ] {1,2,3}时,又开辟了一块内存,这个内存存储就是引用类型的变量,里面保存的时数组array的数组起始位置的地址。
(3)当我们将数组array传参进入到方法func时,相当于int [ ] arr = array。即数组arr接收了array的地址。
(4)当我们执行func方法中的arr [0] = 99;时,此时根据arr的地址,开始根据地址进入数组的内存来查找对应的数据内存位置并修改数据,将arr [0] 的值1改为99。
(5)此时已经将arr[0]地址中的数据修改成99,那么从实参array来从方法func中的传参arr来获取arr[0]的值,其本质上也就是获取arr地址上的值,即99。因为array[0]的地址就是arr[0]的地址,同一个地址上只能存在一个数据,修改后的数据覆盖了修改前的数据,如果没有其他改变,导出后就是修改后的数据。
空引用null
null在java中就表示空引用,即无效的应用,当一个数组初始化为null时,这个数组时无效的,即执行输出就会抛出为空指针异常。
但如果在执行过程中,让数组array = null,则就会让数组成为null,而不是执行输出空指针异常。
示例:
import java.util.Arrays;
public class Array {
public static void main(String[] args) {
int [] array = {1,2,3};
System.out.println(array);//输出数组的地址
System.out.println("_________________");
//输出数组的数据
System.out.println(Arrays.toString(array));
System.out.println("*****************");
array = null;
System.out.println(array);//输出数组的地址
System.out.println("=================");
//输出数组内的数据
System.out.println(Arrays.toString(array));
}
}
结果:
[I@1b6d3586
_________________
[1, 2, 3]
*****************
null
=================
null
null执行后,表示其数组是为空。那么其地址也是空。
初识JVM内存区域划分
在JVM中内存被划分了几个区域。线程,堆,方法区。线程中包括了程序计数器,虚拟机栈和本地方法栈。方法区还囊括了运行时常量池。堆、方法区和运行时常量池只有一份,而线程可以有很多份,那么同样的程序计数器,虚拟机栈和本地方法栈也存在很多份。
程序计数器(PC Register):只是一个很小的空间,保存下一条执行的指令的地址。
虚拟机栈(JVM Stack):存储局部变量表和其他信息。
本地方法栈(Native Method Stack):本地方法栈与虚拟机栈的作用类似。只不过保存的内容时Native方法的局部变量。
堆(Heap):JVM所管理的最大内存区域。使用new创建的对象都是在堆上保存。
方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据。方法编译出的字节码也保存在这个区域。
运行时常量池(Runtime Constant Pool):是方法区的一部分,存放字面量(字符串常量)与符号引用。(从JDK1.7开始,运行时常量池在堆上)。
二维数组
二维数组相比一维数组就像是线到面。二维数组其本质上是特别的一维数组,只不过它的数组元素分别是又各是一个一维数组。
基本语法:
数据类型 [ ] [ ] 数组名称 = new 数据类型 [行数] [列数] {初始化数据};
示例:
public class Array {
public static void main(String[] args) {
int[][] array = {
{1,2,3,4},
{2,3,4,5},
{3,4,5,6}
};
for(int row = 0;row < array.length;row++){
for (int col = 0;col <array[row].length;col++){
System.out.printf("%d\t",array[row][col]);
}
System.out.println("");
}
}
}
1 2 3 4
2 3 4 5
3 4 5 6
二维数组的用法和一维数组没有明显的差别。