[Java SE] 数组的定义与使用(二):数组的应用与常用方法

1.数组转字符串

int [] array = {0,1,2,3,4}
System.out.println(Arrays.toString(array));
//调用Arrays类中重写的toString方法
//执行结果:[0,1,2,3,4]

这里使用了Arrays类中重写的toString方法,源码如下:
为了大家方便阅读代码,我们在其中添加注释

public static String toString(int[] a) {
        if (a == null)
            return "null";//数组为null返回null
        int iMax = a.length - 1;
        if (iMax == -1)//数组为空返回空数组(a.length==0)
            return "[]";

        StringBuilder b = new StringBuilder();//创建StringBuilder
        b.append('[');//首先为b添加“[”
        for (int i = 0; ; i++) {
            b.append(a[i]);//遍历数组,为b添加元素
            if (i == iMax)
                return b.append(']').toString();//遍历到数组最后停止,并添加“]”
            b.append(", ");
        }
    }

2.数组拷贝

public static void func(){
	// newArr和arr引用的是同一个数组
	// 因此newArr修改空间中内容之后,arr也可以看到修改的结果
	int[] arr = {1,2,3,4,5,6};
	int[] newArr = arr;
	newArr[0] = 10;
	System.out.println("newArr: " + Arrays.toString(arr));
	// 使用Arrays中copyOf方法完成数组的拷贝:
	// copyOf方法在进行数组拷贝时,创建了一个新的数组
	// arr和newArr引用的不是同一个数组
	arr[0] = 1;
	newArr = Arrays.copyOf(arr, arr.length);
	System.out.println("newArr: " + Arrays.toString(newArr));
	// 因为arr修改其引用数组中内容时,对newArr没有任何影响
	arr[0] = 10;
	System.out.println("arr: " + Arrays.toString(arr));
	System.out.println("newArr: " + Arrays.toString(newArr));
	// 拷贝某个范围.
	int[] newArr2 = Arrays.copyOfRange(arr, 2, 4);
	System.out.println("newArr2: " + Arrays.toString(newArr2));
}

我们前面说到,数组类型的对象是引用对象,所以我们通过画堆和栈的方法来解释以上的代码:

  • 第一段代码:
    在这里插入图片描述
  • 第二段代码
    在这里插入图片描述
  • 第三段代码
    在这里插入图片描述
    以下是关于copyOf和copyOfRage的源码:
    我们还是通过注释解释
public static int[] copyOf(int[] original, int newLength) {//原数组和新数组的长度
        int[] copy = new int[newLength];//创建新数组,所以对原来的数组没有影响
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));//该行代码实现源码比较复杂,这里不多解释
        return copy;//返回复制后的数组
    }

在后期我们学习数据结构的时候,会反复使用该方法对顺序表,优先级队列,栈等的数据结构进行扩容。
我们下面使用一个简单的方法实现一个自己的copyOf方法

 public int[] myCopyOf(int[] array,int newLength){
        int [] newArray = new int[newLength];
        for (int i = 0; i < array.length; i++) {
            newArray[i] = array[i];
        }
        return newArray;
    }

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.顺序查找数组元素

public static void main(String[] args) {
	int[] arr = {1,2,3,10,5,6};
	System.out.println(find(arr, 10));
}
public static int find(int[] arr, int data) {
	for (int i = 0; i < arr.length; i++) {
	if (arr[i] == data) {
		return i;
		}
	}
	return -1; // 表示没有找到
}
// 执行结果
//3分为

上述代码在查找上有缺陷,这种方法很慢,我们下面介绍一种比较高效的方法

5.二分查找数组元素

这种方法虽然相较顺序查找比较高效,但是也有一定的限制,这种方法只对有序数组生效,那么什么叫有序数组?有序数组分为升序和降序,如:1 2 3 4, 4 3 2 1,我们以升序数组为例
二分查找的大体思路为:

  • 把索要查找的元素和中间的元素进行比较
  • 若等于中间元素,则要查找的元素就是中间元素
  • 若小于中间元素,则去数组左侧查找
  • 若大于中间元素,则去数组右侧查找
public static void main(String[] args) {
	int[] arr = {1,2,3,4,5,6};
	System.out.println(binarySearch(arr, 6));
}
public static int binarySearch(int[] arr, int toFind) {
	int left = 0;
	int right = arr.length - 1;
	while (left <= right) {
	int mid = (left + right) / 2;
	if (toFind < arr[mid]) {
	// 去左侧区间找
	right = mid - 1;
	} else if (toFind > arr[mid]) {
	// 去右侧区间找
	left = mid + 1;
	} else {
	// 相等, 说明找到了
	return mid;
	}
	}
	// 循环结束, 说明没找到
	return -1;
	}
	// 执行结果
	//5

6.数组的排序

给定一个数组,我们来将这个数组排序,排列为升序或降序,假设我们要排升序

  1. 我们排序时可以使用冒泡排序法,当然,冒泡排序法只是其中一种方法,在后续学习数据结构时,我们会学习更多排序方法,例如:堆排序,快速排序等

冒泡排序大体思路:

  • 确定排序趟数
  • 确定每一趟排序的次数
  • 第一趟,从开头开始,将相邻元素两两比较,第二趟,从第二个元素开始,重复第一次的操作…

我们通过一个动图来形象地描述冒泡排序:
在这里插入图片描述
我们通过代码来实现:

public static void main(String[] args) {
	int[] arr = {9, 5, 2, 7};
	bubbleSort(arr);
	System.out.println(Arrays.toString(arr));
}
public static void bubbleSort(int[] arr) {
	for (int i = 0; i < arr.length; i++) {
		for (int j = 1; j < arr.length-i; j++) {
			if (arr[j-1] > arr[j]) {
			int tmp = arr[j - 1];
			arr[j - 1] = arr[j];
			arr[j] = tmp;
			}
		}
	} // end for
} // end bubbleSort
// 执行结果
//[2, 5, 7, 9]
  1. 我们也可以使用选择排序来排序

大体思路:

  • 先把第一个数据作为最小数据,之后一一与后面的元素进行比较
  • 若遇到比第一个元素小的元素,则替换最小元素
  • 遍历到最后,将第一个与最小元素交换
  • 走到第二个元素,重复上述操作
    我们依然通过动图来解释:
    在这里插入图片描述
    代码如下:
 public int[] selectSort(int[] array){
        for (int i = 0; i < array.length; i++) {
            int minIndex = i;
            int j = i+1;
            for (; j < array.length; j++) {
                if(array[j]<array[minIndex]){
                    minIndex = j;
                }
            }
            int tmp = array[minIndex];
            array[minIndex]=array[i];
            array[i] = tmp;
        }
        return array;
    }

冒泡排序性能较低. Java 中内置了更高效的排序算法,即sort方法

public static void main(String[] args) {
	int[] arr = {9, 5, 2, 7};
	Arrays.sort(arr);
	System.out.println(Arrays.toString(arr));
}

Java系统中实现sort方法的底层排序方法是快速排序,我们后续介绍

7.数组逆序

给定一个数组, 将里面的元素逆序排列.
思路:

  • 设定两个下标, 分别指向第一个元素和最后一个元素. 交换两个位置的元素.
  • 然后让前一个下标自增, 后一个下标自减, 循环继续即可.

代码示例:

public static void main(String[] args) {
	int[] arr = {1, 2, 3, 4};
	reverse(arr);
	System.out.println(Arrays.toString(arr));
}
public static void reverse(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--;
	}
}

8.二维数组

二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组

  • 基本语法:
    数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
  • 代码实例
int[][] arr = {
	{1, 2, 3, 4},
	{5, 6, 7, 8},
	{9, 10, 11, 12}
	};
for (int row = 0; row < arr.length; row++) {
	for (int col = 0; col < arr[row].length; col++) {
		System.out.printf("%d\t", arr[row][col]);
	}
	System.out.println("");
}
// 执行结果
1 2 3 4
5 6 7 8
9 10 11 12

二维数组在后面其实使用的比较少,我们在后面使用二维数组时一般都是通过顺序表结合泛型来创建

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值