数组
- 回顾复习
- 四、数组练习
- 1. 数组转字符串
- 2. 数组拷贝
- 五、 二维数组
回顾复习
数组
- 定义:数组是一块连续的内存,存储相同类型的数据
- 数组的使用(三种方式)
局部变量存储在栈上
数组–引用(变量):存储的是其所指向对象的地址 - 补充:
JVM五部分:Java虚拟机栈、本地方法栈、堆、方法区、程序计数器 - 引用型变量未指向任何对象时,只能赋值为null,注意不是0!
不能输出该引用变量长度or带下标的具体值,会出现空指针溢出异常 - 下标超过其数组本身长度也会出现异常:下标越界异常
- 遍历数组:
for(int i =0; i< 数组名.length;i++) { }
for-each: for(元素类型 变量x:数组名) {sout(x);//打印变量x}
(用的最多)String ret = Arrays.toString(数组名);
sout(ret); //将数组以字符串形式进行输出 类似[1,2,…] - 方法以及传参:数组传参传入的是 引用指向对象的地址–因为该引用存储的就是对象的地址(相当于传址调用)
补:形参数组–元素类型[] 数组名 - 传参不改变原来数组数据
- 通过new改变–引用变量指向的是新开辟的对象地址–即:修改指向
- 通过下标–直接改变原来数组对象
- 方法调用结束后,其所在栈区会被回收,但是当其返回值(数组返回值是其所指向对象的地址)被接收后,其指向对象就没有被销毁
- 练习
import java.util.Arrays;
/**
* 用于测试--csdn书写
*/
public class Test {
//测试数组
public static void test1(int[] array1) {
array1 = new int[]{1,2,3,4,5};
}
public static void test2(int[] array2) {
array2[0] = 99;
}
public static void main(String[] args) {
int[] array1 = {5,6,7,8,9};
int[] array2 = {77,88,99};
System.out.println("======改变前======");
System.out.println("array1:"+ Arrays.toString(array1));
System.out.println("array2:"+ Arrays.toString(array2));
System.out.println("======改变后======");
test1(array1);
test2(array2);
System.out.println("array1:"+ Arrays.toString(array1));
System.out.println("array2:"+ Arrays.toString(array2));
}
}
- 结果:
- 分析:
四、数组练习
1. 数组转字符串
自己实现toString方法
提示:利用String的拼接!
(注:String类型和其他数据类型进行拼接的时候,会整体变成字符串)
注意判断是否null–java也有asssert ,但是很少用
- 代码:
import java.util.Arrays;
/**
* 数组转字符串
* 实现一个方法 toString, 把一个整型数组转换成字符串. 例如数组 {1, 2, 3} ,
* 返回的字符串为 "[1, 2, 3]", 注意 逗号 的位置和数量.
*/
public class ToString {
public static String toString(int[] array) {
if(array != null) {
String copy = "[";
for (int i = 0; i < array.length; i++) {
copy += array[i] ;
if(i != array.length-1) {
copy += ","+" ";
}
}
copy += "]";
return copy;
} else {
return "null";
}
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 8, 9, 10};
int[] arr = null;
System.out.println("======原数组======");
System.out.println(Arrays.toString(array));
System.out.println("======字符串======");
System.out.println(toString(array));
System.out.println("======原数组======");
System.out.println(Arrays.toString(arr));
System.out.println("======字符串======");
System.out.println(toString(arr));
}
}
- 结果:
2. 数组拷贝
- 拷贝两个条件:
1)原来的
2)复制出来一个相同的数组–新的空间(与之前大小一样)–注意是不同空间!! - 数组拷贝的五种方法:
(注意库函数的返回类型)
- 方法一:模拟实现-for循环
-代码:
-结果: - 方法二:int [] 数组名 = Arrays.copyOf(数组名,长度–如:数组名.length);
(数组长度大于原来长度–可用于扩容,不够的补0) - 方法三:补充:部分拷贝:Arrays.copyOfRange(数组名,起始下标,结束下标); //[,) 前闭后开
(struct–idea中关注一下)
注意:看源码如果看到native–说明其底层是c、c++实现的,兼容性稍好,速度更快 - 方法四:System.arraycopy(你要拷贝的数组名,哪个下标开始考,拷贝到哪个数组,拷贝到数组的哪个位置开始,拷贝多长); – 合法范围,不能越界 --直接来,不用再写新的数组接收
(补充:Object是祖宗类,可以接收任意类型数据)
-代码:
-结果: - 方法五:int [] 数组名 = 原来数组名.clone(); --产生副本,但是地址不相同
五、 二维数组
定义方式:
1.int[][] 数组名 = {{},{},…};
2.int[][] 数组名 = new int[][]{{},{},…};
3.int[][] 数组名 = new int[r][c];
每一行可以看做一个一维数组,则数组名.length表示一维数组个数,即:行数
列数表示为数组名[i].length; //每个一维数组长度
THINK
回顾小结:
- 二维数组定义三种方式(最后一种方式行列不可省略:即:int[][] 数组名 = new int[r][c]; )
- 二维数组每一行看为一个一维数组,所以遍历数组方式:
行:数组.length;
列:数组[i].length - 二维数组是特殊的一维数组
1. for-each遍历:for(每个元素相当于一个一维数组 int[] tmp:数组名){
for(int x(每个元素): 一维数组名tmp)
sout(x);
}
- 遍历二维数组方式三:Arrays.deepToString(数组名);
(遍历二维数组:1)for循环
2)for-each循环
3)Arrays.deepToString(数组名);) - 补充区别:C语言列不可以省略;java中列可以省略,行不可以省略(二维数组n)
如果列省略,打印数组就是n个null(n表示行数); - 赋值或者创空间:在数组省略了列的条件下
数组名[i] = new int[j]; i行共有j个元素(未初始化则赋值为0)
–叫做不规则数组
-不能同时决定列和赋值
*注意点:
当二维数组省略列时且未进行赋值时,表示的是一个一维数组且每个元素都是null;
当该二维数组的每一行进行new 数据类型[n] 时,就成为了二维数组,并且若赋值不一致则为不规则数组(详见上),打印时需要使用Arrays.deepToString(数组名)。