数组的定义和使用(下)
- 4. 数组练习
- 4.1 模拟实现toString
- 4.2 数组拷贝
- 4.3 比较两个数组是否相同
- 4.4 填充数组
- 4.3 求数组中元素的平均值
- 4.4 查找数组中指定元素(顺序查找)
- 4.5 查找数组中指定元素(二分查找)
- 4.6 数组排序(冒泡排序)
- 4.7 数组逆序
- 5. 二维数组
4. 数组练习
4.1 模拟实现toString
public static String my_toString(int[] arr) {
String ret = "[";
for (int i = 0; i < arr.length; i++) {
if(i == arr.length - 1) {
ret += arr[i] + "";
break;
}
ret = ret + arr[i] + ", ";
}
ret += "]";
return ret;
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
System.out.println(my_toString(arr));
System.out.println(Arrays.toString(arr));
}
//---------------
//编译器运行结果为
//[1, 2, 3, 4, 5]
//[1, 2, 3, 4, 5]
或者
public static String my_toString(int[] arr) {
String ret = "[";
for (int i = 0; i < arr.length; i++) {
ret = ret + arr[i] ;
if(i != arr.length - 1) {
ret += ", ";
}
}
ret += "]";
return ret;
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
System.out.println(my_toString(arr));
System.out.println(Arrays.toString(arr));
}
//-------------
//编译器运行结果为
//[1, 2, 3, 4, 5]
//[1, 2, 3, 4, 5]
但是为了防止实参为空指针的情况,所以我们应该进行判定。
public static String my_toString(int[] arr) {
//判定是否为空指针
if(arr == null) {
return "null";
}
String ret = "[";
for (int i = 0; i < arr.length; i++) {
ret = ret + arr[i] ;
if(i != arr.length - 1) {
ret += ", ";
}
}
ret += "]";
return ret;
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
System.out.println(my_toString(arr));
System.out.println(Arrays.toString(arr));
}
4.2 数组拷贝
这种情况属于数组拷贝吗?
public static void main(String[] args) {
int[] array = {1, 2, 3, 4};
System.out.println(Arrays.toString(array));
int[] array2 = array;
System.out.println(Arrays.toString(array2));
}
//--------
//编译器运行结果为
//[1, 2, 3, 4]
//[1, 2, 3, 4]
不属于,因为这里的对象只有一个,只是把对象的地址拷贝了过来而已。
数组拷贝的结果应该出现两个对象。
代码示例
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
int[] copyArr = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
copyArr[i] = arr[i];
}
System.out.println(Arrays.toString(copyArr));
System.out.println(Arrays.toString(arr));
}
//-------------
//编译器运行结果为
//[1, 2, 3, 4, 5]
//[1, 2, 3, 4, 5]
在Java当中其实我们有对数组拷贝的方法一****Arrays.copyof
public static int[] copyOf(int[] original, int newLength)
返回值为拷贝好的数组的地址
代码示例
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
int[] ret = Arrays.copyOf(arr,arr.length);
System.out.println(Arrays.toString(ret));
}
//--------------
//编译器运行结果为
//[1, 2, 3, 4, 5]
也可以当作扩容来用
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
int[] ret = Arrays.copyOf(arr,arr.length*2);
System.out.println(Arrays.toString(ret));
}
//-----------
//编译器运行结果为
//[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
补充
在copyof
方法中用到了arraycopy
方法二。
下面是arraycopy
的使用示例。
public static void main(String[] args) {
int[] array = {1,2,3,4};
int[] copy = new int[array.length];
System.arraycopy(array,0,copy,0,array.length);
//拷贝那个数组,从(源)数组的哪个位置开始复制,拷贝到哪个数组,从(目标)数组的哪个位置开始粘贴,拷贝多长
}
还有拷贝的方法三是**Arrays.copyOfRange
**
public static void main(String[] args) {
int[] arr = {1,2,3,4};
int[] ret = Arrays.copyOfRange(arr,1,3);
System.out.println(Arrays.toString(ret));
}
--------------
编译器运行结果为
[2, 3]
原因:
在Java当中像这种from...to...
的情况下范围是左闭右开的。
方法四
代码示例
public static void main(String[] args) {
int[] arr = {1,2,3,4};
int[] arr2 = arr.clone();
System.out.println(Arrays.toString(arr2));
}
//---------
//编译器运行结果为
//[1, 2, 3, 4]
clone
克隆的意思就是产生一个副本(深拷贝)
深拷贝与浅拷贝
4.3 比较两个数组是否相同
用到的方法是Arrays.equals()
public static boolean equals(int[] a,int[] a2)
如果两个数组相同,则返回true,否则返回false
代码示例
public static void main(String[] args) {
int[] arr1 = {1,2,3,4};
int[] arr2 = {1,2,3,4};
System.out.println(arr1 == arr2);
System.out.println(Arrays.equals(arr1,arr2));
}
//----------
//编译器运行结果为
//false
//true
如果仅仅是简单的比较是否相等,那么比较的两个数组的地址。
4.4 填充数组
Arrays.fill
public static void fill(int[] a,int val)
//a是填充的数组,val是存储在数组的所有元素中的值
代码示例
public static void main(String[] args) {
int[] arr = new int[10];
Arrays.fill(arr,-1);
System.out.println(Arrays.toString(arr));
}
//-----------
//编译器运行结果为
//[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
也可以指定范围进行填充
public static void fill(int[] a,int fromIndex,int toIndex,int val)
//a填充的数组,fromIndex起始位置,toIndex终止位置,val填充的数字。
但是是左闭右开的。
代码示例
public static void main(String[] args) {
int[] arr = new int[10];
Arrays.fill(arr,2,3,-1);
System.out.println(Arrays.toString(arr));
}
------------
编译器运行结果为
[0, 0, -1, 0, 0, 0, 0, 0, 0, 0]
补充
在Java当中我们在Arrays
中经常用到的有
sort()
toString()
fill()
copyOf()
4.3 求数组中元素的平均值
代码示例
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
System.out.println(avg(arr));
}
public static double avg(int[] arr) {
int sum = 0;
for (int x : arr) {
sum += x;
}
return (double)sum / (double)arr.length; }
// 执行结果
3.5
注意的是求平均值的时候要进行强制类型转换。
4.4 查找数组中指定元素(顺序查找)
public static int findElement(int[] arr,int val) {
for (int i = 0; i < arr.length; i++) {
if(arr[i] == val) {
return i;
}
}
return -1;
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
System.out.println(findElement(arr, 4));
}
//------------
//编译器运行结果为
//3
4.5 查找数组中指定元素(二分查找)
4.6 数组排序(冒泡排序)
4.7 数组逆序
public static int[] reverseArray(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--;
}
return arr;
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
System.out.println(Arrays.toString(reverseArray(arr)));
}
//-----------
//编译器运行结果为
//[5, 4, 3, 2, 1]
5. 二维数组
二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组。
创建二维数组
方式一
int[][] arr = {{1,2,3},{4,5,6}};
方式二
int[][] arry = new int[][]{{1,2,3},{4,5,6}};
方式三
int[][]arr = new int[2][3];
遍历二维数组方法一
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
//-------------
//编译器运行结果为
//1 2 3
//4 5 6
补充
二维数组就是特殊的一维数组
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6}};
System.out.println(Arrays.toString(arr[0]));
System.out.println(Arrays.toString(arr[1]));
}
//--------------
//编译器运行结果为
//[1, 2, 3]
//[4, 5, 6]
求数组的行数和列数
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6}};
System.out.println(arr.length);
System.out.println(arr[0].length);
}
//--------------
//编译器运行结果为
//2
//3
所以我们的数组遍历方法二就可以写成
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
//---------
//编译器运行结果为
//1 2 3
//4 5 6
数组遍历方法三
for-each
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6}};
for (int[] x:arr) {
for (int y:x) {
System.out.print(y + " ");
}
}
}
//-------------
//编译器运行结果为
//1 2 3 4 5 6
数组遍历方法四
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6}};
System.out.println(Arrays.deepToString(arr));
}
//-------------
//编译器运行结果为
//[[1, 2, 3], [4, 5, 6]]
不规则数组
public static void main(String[] args) {
int[][] arr = new int[2][];//在Java当中,行不可以省略,列可以省略
//如果不进行指定行初始化的话,那么arr[0],arr[1]里面存放的是null
arr[0] = new int[2];
arr[1] = new int[4];
System.out.println(Arrays.deepToString(arr));
}
//------------
//编译器运行结果为
//[[0, 0], [0, 0, 0, 0]]
当然这种不规则数组一定要进行赋值,否则会报空指针异常。
因为
public static void main(String[] args) {
int[][] arr = new int[2][];
System.out.println(arr[0]);
System.out.println(arr[1]);
}
//------------
//运行结果为
//null
//null
补充
栈上放的是局部变量
引用一定在栈上吗?不是的,在不在栈上和引用没有关系,只看是不是局部变量。