目录
数组的定义和访问
数组:数组是用来存储相同类型的数据、长度确定的容器
定义
格式
DataType[] ArrayName = new DataType[Length];
格式解析
- DataType:数组的数据类型
- []:表示数组
- ArrayName:数组名称
- new:创建数组使用的关键字
- Length:数组的长度,一旦确定不可更改
- 举例:
//创建一个长度为5、用来储存int类型数据、名字为arr的整型数组
int[] arr = new int[5];
引申格式
DataType[] ArrayName = new DataType[] {e1, e2, e3...};//e表示元素
String[] strarr = new String[] {"Susan", "Tom", "Jack"};
DataType[] ArrayName = {e1, e2, e3...};
double[] ddarr = {1.1, 1.2, 1.3};
访问
索引
存储到数组内的元素会拥有一个编号,编号从0开始,这个编号即是数组的索引(index),可以通过索引访问数组内的元素。
访问格式
通过数组名ArrayName与索引index即可访问该元素,在Java中每个数组都拥有一个长度,可以通过ArrayName.length获得数组ArrayName的长度L,索引的最大值为(L-1)。
通过这种访问方式,可以获取元素的值,也可以对元素重新赋值。
ArrayName[index], index >= 0, index < ArrayName.length - 1;
public class Array01 {
public static void main(String[] args) {
//Create an array
int[] a = new int[5];//动态初始化
String[] b = new String[]{"Hello", "World"};//静态初始化
int[] c;
c = new int[]{1, 2, 3};//静态初始化的拆分格式
int[] d;
d = new int[5];//动态初始化的拆分格式
String[] e = {"Hello", "Java"};//静态初始化省略格式,不可拆分
System.out.println(d);//[I@10f87f48直接打印数组名称显示内存地址的哈希值,‘[’表示是数组
System.out.println(d[1]);//使用动态初始化不同数据类型的默认值:int->0, double/float->0.0, char->'\u0000', boolean->false, 引用类型->null
//静态初始化也有默认值的过程,不过立刻被替换成具体值
}
}
数组内存分布
内存是计算机重要组成部分,程序从存放的硬盘移入内存后才能运行,程序结束后清空内存。
Java虚拟机的内存划分
Java对空间进行了不同的划分,每块区域均有特定的数据处理方式和内存管理方式。
- 寄存器(Register):给CPU使用,与开发无关。
- 本地方法栈(Native Method Stack):JVM在使用操作系统功能的时候使用,与开发无关。
- 方法区(Method Area):存储可以运行的class文件。
- 堆内存(Heap):存储对象或者数组,通过new来创建的,都存储在堆内存。
- 默认值:int->0, double/float->0.0, char->'\u0000', boolean->false, 引用类型->null
- 方法栈(Stack):方法运行时使用的内存,比如main方法运行,进入方法栈中执行。
举例说明
//下面这个例子说明了数组的内存分布
/*
* 1.Stack(栈):存放的是方法中的局部变量,存在作用域,方法的运行一定在栈中
* 2.Heap(堆):通过new产生的变量开辟的内存区
* 默认值:int->0, double/float->0.0, char->'\u0000', boolean->false, 引用类型->null
* 3.Method Area(方法区):存储.class相关信息,包含方法的信息
* 4.Native Method Stack(本地方法栈):与操作系统相关
* 5.pc Register(寄存器):与CPU相关
* */
public class Array02Memory {
public static void main(String[] args) {
int[] array = new int[3];
System.out.println(array);//[I@10f87f48
array[0] = 10;
System.out.println(array[0]);//10
/* 内存变化情况
* Method Area:
* public static void main(String[] args)
* ...
* Stack:
* main(String[] args)
* int[] array --> 0x10f87f48 * Heap:0x10f87f48
* System.out.println(array) * ⬆(打印array地址值)
* array[0] = 10 0 --> 10 * 修改Heap区array[0]的内容
* System.out.println(array[0]) * 打印Heap区array[0]的内容
* ...
* Heap:
* new int[3](default:0) Addr:0x10f87f48
* [0] 0 --> 10 (after changing)
* [1] 0
* [2] 0
* ...
* */
int[] array_copy = array;//赋值,array_copy与array有相同的地址,指向相同的数组
System.out.println(array_copy);//0x10f87f48
//System.out.println(array[3]);//数组索引越界
/*
空指针异常,没有new初始化
且:如果只是int[] arr = null也是空指针异常
int[] arr;
System.out.println(arr[0]);
*/
}
}
数组的简单操作
数组遍历
所谓数组遍历,就是依次获取数组内的所有元素,也就是依次访问索引0~length-1元素的值,使用一个for循环即可完成。
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
例:获取一个数组中的最大值。
public static void main(String[] args) {
int[] arr = { 5, 15, 2000, 10000, 100, 4000 };
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
System.out.println("Max Value: " + max);
}
数组反转
- 数组反转:将数组中的元素顺序颠倒,如1,2,3,4反转后为4,3,2,1。
- 实现思想:
- 反转即是将数组远端的元素对称交换
- 定义索引分别指向数组两端,交换索引指向位置的值,然后两索引向中间靠拢
- 如果左边索引大于右边索引,说明所有数据交换完成,反转成功
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
for (int min = 0, max = arr.length ‐ 1; min <= max; min++, max‐‐) {
//min为左索引,max为右索引,初始值分别为最小、最大索引值,通过min++, max‐‐向中间靠拢,反转结束标志为min > max
int temp = arr[min];
arr[min] = arr[max];
arr[max] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
数组在方法中的应用
数组可以作为方法的入口参数和返回值,实际上是数组地址参与,举例说明。
public class Array04Parameter {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7};
int[] array_ = pcArray(array);
System.out.println("address:" + array_);
}
//任何数据类型都能作为方法的参数和返回值
//方法的参数为基本类型时,传递的是数据值;方法的参数为引用类型时,传递的是地址值。
//数组作为参数和返回值时,传递和返回的实际上是地址
public static int[] pcArray(int[] arr) {
int[] arr_ = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
arr_[i] = arr[i] + 1;
}
return arr_;
}
}