数组的定义与使用
1. 数组基本用法
1.1 什么是数组1.2 创建数组1.3 数组的使用
1.获取长度2.访问元素3.修改元素4.输出数组 2. 数组作为方法的参数
2.1 基本用法2.2 如何理解引用,形参,实参(重点)2.3 认识null2.4 初识JVM内存区域划分 3. 数组作为方法的返回值4. 数组练习
4.1 实现一个自己版本的数组转字符串4.2 输出一个数组中的最大值4.3 给定一个整型数组,求出数组中元素的平均值4.4 无序数组找某个元素的下标4.5 有序数组找某个元素的下标(二分查找)4.6 判断一个整型数组是否是升序的4.7 数组排序(冒泡排序)4.8 数组排序 用Arrays.sort排序4.9 用Arrays.fill 填充数组4.10 数组逆置4.11 整型数组数字排列,偶数在前,奇数在后4.12 数组的拷贝 5. 二维数组
1. 数组基本用法 1.1 什么是数组数组的本质就是让我们能“批量”创建相同类型的变量
例如:
如果要创建两个变量: int a; int b;
如果要创建多个变量,就需要使用数组
注意事项:在Java中,数组中包含的变量必须的相同类型
1.2 创建数组基本语法:
数据类型[ ] 数组名称 = {初始化数据}
数据类型[ ] 数组名称 = new 数据类型 [ 数组大小 ]
数据类型[ ] 数组名称 = new 数据类型[ ] {初始化数据}
public static void main(String[] args) {
int[] array = {1, 2, 3,};
int[] array1 = new int[3];
int[] array2 = new int[]{1, 2, 3};
1.3 数组的使用
1.获取长度
int[] array = {1,2,3};
System.out.println("length: " + array.length);
//执行结果:
3
2.访问元素
int[] array = {1,2,3};
System.out.println(array[0]);
System.out.println(array[1]);
//执行结果:
1
2
3.修改元素
int[] array = {1,2,3};
array[1] = 20;
System.out.println(array[1]);
//执行结果:
20
4.输出数组
int[] array = {1, 2, 3, 4, 5, 6};
//array是一个引用变量,引用指向一个对象,引用存储的是变量的地址
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
//执行结果:
1 2 3 4 5 6
int[] array = {1,2,3,4,5,6};
for(int x : array){
System.out.print(x + " ");
}
//执行结果:
1 2 3 4 5 6
int[] array = {1,2,3,4,5,6};
//Arrays.toString(数组名) 将参数中的数组以字符串的形式输出
String ret = Arrays.toString(array);
System.out.println(ret);
System.out.println(Arrays.toString(array));
//执行结果:
[1,2,3,4,5,6]
[1,2,3,4,5,6]
数组的使用注意事项
使用 arr.length 能够获取到数组的长度, . 这个操作为成员访问操作符,后面在面向对象中会经常到使用 [ ] 按下标取数组元素. 需要注意, 下标从 0 开始计数使用 [ ] 操作既能读取数据, 也能修改数据.下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常
2. 数组作为方法的参数
2.1 基本用法
代码示例:打印数组内容
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
print(array);
}
public static void print(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
//执行结果
1 2 3 4 5 6
注意事项:print方法中的array是形参,main函数中array是实参
2.2 如何理解引用,形参,实参(重点)public static void func1(int[] array) {
array = new int[]{7, 8, 9, 4, 5, 6};//假设形参array引用 指向的地址是0x45
}
public static void func2(int[] array) {
array[0] = 99;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6}; //假设实参array引用 指向的地址是0x12
System.out.println(Arrays.toString(array));
func1(array);//调用func1 将实参array指向的地址 传给fun1的形参array 形参array也指向0x12
//在fun1内 只是将形参array指向的地址变为了0x56 实参array指向的地址仍是0x12
System.out.println(Arrays.toString(array));//打印的是实参array 指向0x12 所以结果是[1,2,3,4,5,6]
func2(array);//调用func2 将实参array指向的地址 传给func2的形参array 形参array也指向0x12
//在func2内,将形参array指向的地址0x12 的0下标的值改成了99
System.out.println(Arrays.toString(array));
// 因为实参指向的地址是0x12 而0x12中 0 下标的值被改成了99
// 所以结果是[99,1,2,3,4,5,6]
}
在函数内部修改数组内容,函数外部也发生改变。此时数组名array是一个“引用”,当传参的时候,是按照引用传参,引用可以理解为指针,一个引用只能保存一个对象的地址,Java将数组设定成引用类型,进行数组传参时,只是将数组的地址传入到方法形参中.
2.3 认识nullnull在Java中表示"空引用",也就是一个无效的引用
int [] array = null; System.out.println(arr[0]); //执行结果 :空指针异常 Exception in thread "main" java.lang.NullPointerException
null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会抛出 NullPointerException
2.4 初识JVM内存区域划分JVM 的内存被划分成了几个区域
程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址.
虚拟机栈(JVM Stack): 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] array 这样的存储地址的引用就是在这里保存.引用不一定在栈上,如果变量的性质是局部变量,它一定在栈上,实例成员变量不一定在栈上。
本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.
堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[{1, 2,3} ]
方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后代码等数
据. 方法编译出的的字节码就是保存在这个区域.
运行时常量池(Runtime Constant Pool): 是方法区的一部分, 存放字面量(字符串常量)与符号引用. (注意 从 JDK1.7 开始, 运行时常量池在堆上).
局部变量和引用保存在栈上, new 出的对象保存在堆上.
堆的空间非常大, 栈的空间比较小.
堆是整个 JVM 共享一个, 而栈每个线程具有一份(一个 Java 程序中可能存在多个栈).
代码示例:将数组扩大二倍 (无返回值)
public static void main(String[] args){
int[] array = {1,2,3,4,5,};
transform(array);
System.out.println(Arrays.toString(array));
}
public static void transform(int [] array){
for(int i =0; i < array.length; i++){
array[i] = 2 * array[i];
}
}
//执行结果:
[2,4,6,8,10]
注意事项:这种方法,改变了原数组的值,如果我们不希望破坏原数组,就需要在方法中创建一个新数组,并由方法返回出来
代码示例:将数组扩大二倍(有返回值)
public static void main(String[] args){
int[] array = {1,2,3,4,5,};
int[] ret1 = transform1(array);//定义一个数组ret1 用来接收transform1的返回值
System.out.println(Arrays.toString(ret1));// 打印ret1
System.out.println(Arrays.toString(array));//打印原数组array
}
public static int[] transform1(int [] array){
for(int i = 0; i < array.length; i++){
ret[i] = 2 * array[i]
}
return ret;
}
//执行结果:
[2,4,6,8,10]
[1,2,3,4,5]
这样的话就不会破坏原有数组了.另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比高效
4. 数组练习 4.1 实现一个自己版本的数组转字符串代码示例
public static String myToString(int [] array){
if(array == null){
return null;
}
String str = "[";
for(int i = 0; i
4.2 输出一个数组中的最大值
代码示例
public static void main(String[] args) {
int [] array = {5,12,6,8,9};
System.out.println(maxNum(array));
}
public static int maxNum(int [] array){
if( array.length == 0 || array == null){
return -1;
}
int max = array[0];
for (int i = 1; i < array.length;i++){
if (max < array[i]){
max = array[i];
}
}
return max;
}
先将max设置为数组中的第一个元素,遍历数组,如果某个元素大于max,那么就将它的值赋给max
4.3 给定一个整型数组,求出数组中元素的平均值
代码示例
public static void main(String[] args) {
int [] array = {1,2,3,4,5};
System.out.println(avg(array));
}
public static double avg(int[]array){
int sum = 0;
for (int i = 0; i < array.length; i++){
sum += array[i] ;
}
return (double) sum / (double) array.length;
}
//执行结果:
3.0
注意事项:平均值有可能是小数,所以要用返回值类型是double
4.4 无序数组找某个元素的下标
代码示例
public static void main(String[] args){
int [] array = {8,7,4,5,2,1,3,6,9};
System.out.println(findNum(array,5));
}
public static int findNum(int[]array,int key){
for(int i = 0;i < array.length; i++){
if(array[i] == key){
return i;
}
}
return -1; //表示没找到
}
//执行结果:
3
遍历数组,当某个下标的值和要找的值相等时,返回这个下标,如果没有,则返回-1
4.5 有序数组找某个元素的下标(二分查找)
以升序数组为例, 二分查找的思路是先取中间位置的元素, 看要找的值比中间元素大还是小. 如果小, 就去左边找;否则就去右边找
代码示例
public static void main(String[] args){
int [] array = {1,2,3,4,5,6,7,8,9};
System.out.println(binarySearch(array,6));
}
public static int binarySearch(int [] array,int key){
int left = 0;
int right = array.length - 1;
while(left <= right){
int mid = (left + right) / 2;
if(array[mid] < key){ //在右区间找
left = mid + 1;
}else if(array[mid > key]){//在左区间找
right = mid -1;
}else{ //找到了
return mid;
}
}
return -1; //表示没有找到
}
//执行结果
5
4.6 判断一个整型数组是否是升序的
代码示例
public static void main(String[] args){
int [] array = {1,2,3,8,5,6};
System.out.println(ifup(array));
}
public static boolean ifUP(int [] array){
for(int i = 0; i < array.length - 1; i++){
if( array[i] > array[i+1]){
return false;
}
return true;
}
}
//执行结果
false
注意事项:for循环的边界要小于数组长度减1,否则会下标溢出
4.7 数组排序(冒泡排序)
代码示例:
public static void main(String [] args){
int [] array = {3,5,9,4,8,7,1,6,2}
bubbleSort(array);//调用bubbleSort方法
System.out.println(Assary.toString(array));//输出数组array中的元素
}
public static void bubbleSort(int [] array){
for(int i = 0; i < array.length -1; i++){ //排序的次数
boolean flg = false;
//定义flg 用来记录是否交换,交换为true,没交换为false, 每次排序前flg初始值为false
for(int j = 0; j array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
flg = true; //说明交换了
}
}
if(flg == false){
break; //没交换, 说明排序已经完成,不再需要继续进行后续的循环
}
}
}
//执行结果
[1,2,3,4,5,6,7,8,9]
4.8 数组排序 用Arrays.sort排序
代码示例
public static void main(String[] args) {
int [] array = {3,2,1,6,5,4,7,8,9};
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
//执行结果
[1,2,3,4,5,6,7,8,9]
4.9 用Arrays.fill 填充数组
代码示例
public static void main15(String[] args) {
int [] array = new int [10];
Arrays.fill(array,2,4,55);//在[2,4)下标中放入55
System.out.println(Arrays.toString(array));
}
//执行结果
[0,0,55,55,0,0,0,0,0,0]
4.10 数组逆置
代码示例
public static void main16(String[] args) {
int [] array = {1,2,3,4,5,6,7,8,9};
reverse(array);
System.out.println(Arrays.toString(array));
}
public static void reverse(int[]array){
int i = 0;
int j = array.length-1;
while (i < j){
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
i++;
j--;
}
}
//执行结果
[9,8,7,6,5,4,3,2,1]
4.11 整型数组数字排列,偶数在前,奇数在后
代码示例
public static void main(String[] args) {
int [] array = {1,2,3,4,5,6};
transForm(array);
System.out.println(Arrays.toString(array));
}
public static void transForm(int [] array){
int i = 0;
int j = array.length-1;
while (i < j){
while (array[i] % 2 == 0 && i < j){
i++;
}// 循环结束后i下标的元素一定是奇数
while (array[j] % 2 != 0 && i < j){
j--;
}// 循环结束后j下标的元素一定是偶数
int tmp = array[i];
array[i] = array[j];
array[j] = tmp; //交换两个位置的元素
}
}
//执行结果
[6,2,4,3.5.1]
4.12 数组的拷贝
for循环的拷贝:
public static void main(String[] args) {
int [] array = {1,2,3,4,5,6};
System.out.println(Arrays.toString(copy(array)));
}
public static int[] copy(int [] array){
int [] copy = new int[array.length];
for (int i = 0 ; i < array.length; i++){
copy[i] = array[i];
}
return copy;
}
//执行结果
[1,2,3,4,5,6]
Arrays.copyOf 拷贝:
public static void main(String[] args) {
int [] array = {1,2,3,4,5,6};
int [] ret = Arrays.copyOf(array,array.length);//Arrays.copyOf(拷贝的数组名,拷贝的长度)
System.out.println(Arrays.toString(ret));
//执行结果
[1,2,3,4,5,6]
Arrays.copyOfRange 拷贝
public static void main(String[] args){
int [] array = {1,2,3,4,5,6};
int[] arr = Arrays.copyOfRange(array,1,3);
//拷贝一部分数据,Arrays.copyOfRange(数组名,拷贝范围[1,3) )
System.out.println(Arrays.toString(arr));
}
//执行结果
[2,3]
System.arraycopy 拷贝
public static void main(String[] args){
int [] array = {1,2,3,4,5,6};
int [] copy = new int[array.length];
System.arraycopy(array,0,copy,0,array.length);
//System.arraycopy(源数组,从源数组的0开始拷贝,拷贝到copy数组,从copy的0下标开始,拷贝的长度)
System.out.println(Arrays.toString(copy));
}
//执行结果
[1,2,3,4,5,6]
array.clone 拷贝
public static void main(String[] args){
int [] array = {1,2,3,4,5,6};
int [] array1 = array.clone();//array.clone 克隆一个副本 copy引用指向副本的地址,
System.out.println(Arrays.toString(array1));
}
//执行结果
[1,2,3,4,5,6]
5. 二维数组
二维数组本质上也就是一维数组,只不过每个元素又是一个一维数组
基本语法
数据类型[][] 数组名称 = new 数据类型 [行数] [列数] { 初始化数据 };
代码示例
public static void main(String[] args) {
int [][]array = {{1,2,3},{4,5,6}};
int [][]array2 = new int[][]{{1,2,3},{4,5,6}};
int [][]array3 = new int [2][3];
}
打印二维数组
代码示例1
public static void main(String[] args) {
int [][]array = {{1,2,3},{4,5,6}};
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j]+" ");
}
System.out.println();
}
}
//执行结果
1 2 3
4 5 6
代码示例2
public static void main(String[] args) {
int [][]array = {{1,2,3},{4,5,6}};
for (int[] ret: array) {
for (int x: ret) {
System.out.print(x + " ");
}
System.out.println();
}
}
//执行结果
1 2 3
4 5 6
代码示例3
public static void main(String[] args) {
int [][]array = {{1,2,3},{4,5,6}};
System.out.println(Arrays.deepToString(array));
}
//执行结果
[[1,2,3],[4,5,6]]



