数组的总结

1.数组的基础知识及用法

1.1 为什么要有数组?

  • 为了存储同种类型的多个值
    数组的概念: 数组是存储同一种数据类型多个元素的集合。也可以看成是一个容器。数组既可以存储基本数据类型,也可以存储引用数据类型。

1.2 创建数组

//动态初始化
数据类型[ ] 数组名 = new 数据类型[数组的长度];
//静态初始化
数据类型[ ] 数组名 = {初始化数据};
代码示例

int[] arr = new int[]//动态初始化
  • 注意动态初始化只指定长度,由系统给出初始化值。
int[] arr = {0,1,2,3,4};//静态初始化
  • 静态初始化的时候,数组元素个数与初始化数据的格式是一致的。

1.3 数组的使用

代码示例:获取长度&访问元素

int[] arr = {1, 2, 3};
// 获取数组长度
System.out.println("length: " + arr.length); // 执行结果: 3
// 访问数组中的元素
System.out.println(arr[1]); // 执行结果: 2
System.out.println(arr[0]); // 执行结果: 1
arr[2] = 100;
System.out.println(arr[2]); // 执行结果: 100

注意:下标访问操作不能超出有效范围[0,length - 1],如果超出有效范围,会出现下标越界异常(ArrayIndexOutOfBoundsException)。
代码示例:下标越界

	int[] arr = {0,1,2,3};
	System.out.println(arr[10]);
	//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100
	at Test.main(Test.java:4)

代码示例:空指针异常

	int[] arr = {1,2,3};
	arr = null;
	System.out.println(arr[0]);
//NullPointerException

原因:数组已经不在指向堆内存了,而你还用数组名去访问元素.


代码示例:遍历数组
所谓“遍历”是指将数组中的所有元素都访问一边,通常需要搭配循环语句。

int[] arr = {1, 2, 3};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 执行结果
1
2
3
* 数组的属性:arr.length数组的长度
* 数组的最大索引:arr.length - 1;

代码示例:for-each遍历数组

int[] arr = {1, 2, 3};
for (int x : arr) {
System.out.println(x);
}
// 执行结果
1
2
3

for-each是for循环的另一种使用方式,能够更方便的完成对数组的遍历,可以避免循环条件和更新语句写错。
代码示例:获取最值

public static int getMax(int[] arr) {
		int max = arr[0];
		for (int i = 1;i < arr.length ;i++ ) {	//从数组的第二个元素开始遍历
					if (max < arr[i]) {	//如果max记录的值小于的数组中的元素
						max = arr[i];		//max记录住较大的
					}
				}
				return max;
			}

2.数组的拷贝

2.1 clone 方法

基本数据类型(int,boolean,char,byte,short,float,double,long)都可以直接使用clone方法进行克隆,注意String类型是因为其值不可变才可以使用。
代码示例(int类型)

int[] a1 = {1, 3};
int[] a2 = a1.clone();

a1[0] = 666;
System.out.println(Arrays.toString(a1));   //输出结果[666, 3]
System.out.println(Arrays.toString(a2));   //输出结果[1, 3]

2.2 System.arraycopy

System.arraycopy方法是一个本地的方法,其使用方法为

System.arraycopy(原数组,原数组的开始位置,目标数组,目标数组的开始位置,拷贝个数)

代码示例

int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = new int[10];

System.arraycopy(a1, 1, a2, 3, 3);
System.out.println(Arrays.toString(a1)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)); // [0, 0, 0, 2, 3, 4, 0, 0, 0, 0]

2.3Arrays.copyOf

Arrays.copyOf的用法为

Arrays.copyOf(原数组,拷贝的个数)

代码示例

int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = Arrays.copyOf(a1, 2);

System.out.println(Arrays.toString(a1)) // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)) // [1, 2]

使用该方法时无需事先使用new关键字对对象进行内存单元的分配。

2.4 Arrays.copyOfRange

Arrays.copyOfRange的使用方法为

Arrays.copyOfRange(原数组,开始拷贝,拷贝的个数)

代码示例

int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = Arrays.copyOfRange(a1, 0, 1);

System.out.println(Arrays.toString(a1)) // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)) //[1]

2.5 浅拷贝和深拷贝

浅拷贝:在堆内存中不会分配新的空间,而是增加一个引用变量和之前引用指向相同的堆空间。
深拷贝: 在堆内存中分配新空间,将之前的数组堆内存中的内容拷贝到新的空间中。
以上四种拷贝方法均是深拷贝
**对于数组当中如果是基本类型,那么就是深拷贝。
**对于数组当中如果是引用类型,那么就是浅拷贝。

3 数组的查找及顺序问题

3.1查找数组中指定元素

代码示例:顺序查找
给定一个数组,再给定一个元素,找出该元素在数组中的位置

	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 toFind) {
	for (int i = 0; i < arr.length; i++) {
	if (arr[i] == toFind) {
	return i;
	}
	}
	return -1; // 表示没有找到
	}
	// 执行结果
	3

代码示例:二分查找
针对有序数组, 可以使用更高效的二分查找.
* 啥叫有序数组?
* 有序分为 “升序” 和 “降序”
* 如 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

3.2数组排序

代码示例:检查数组的有序性
给定一个数组,判断该数组是否有序的(升序)

public static void main(String[] args) {
int[] arr = {1,2,3,10,5,6};
System.out.println(isSorted(arr));
}
public static boolean isSorted(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
return false;
}
}
return true;
}

代码示例:冒泡排序
*给定一个数组,让数组升(降)排序,
算法思路
每次尝试找到当前待排序区间中最小(或最大)的元素, 放到数组最前面(或最后面).

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) {
// [0, bound) 构成了一个前闭后开区间, 表示已排序区间
// [bound, length) 构成了一个前闭后开区间, 表示待排序区间
// 每循环一次, 就找到一个合适大小的元素, 已排序区间就增大1.
for (int bound = 0; bound < arr.length; bound++) {
for (int cur = arr.length - 1; cur > bound; cur--) {
if (arr[cur - 1] > arr[cur]) {
int tmp = arr[cur - 1];
arr[cur - 1] = arr[cur];
arr[cur] = tmp;
}
}
} // end for
} // end bubbleSort
// 执行结果
[2, 5, 7, 9]

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

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

4 二维数组

*二维数组本质上也就是一位数组,只不过每个元素又是一个一位数组。
基本语法

数据类型[][] 数组名称 = new 数据类型 [行数][列数];

代码示例

int[][] arr = new int[3][2]; //定义一个三行两列的数组
int[][] arr = {{1,2,3},{4,5},{6,7,8,9}};

二维数组与一维数组的用法没有明显差别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值