1 数组
数组
按一定顺序排列的具有相同数据类型的对象序列或基本类型数据序列。
数组的声明
数据类型[] 变量名;
数据类型 变量名[];
一般使用前一种声明方式,后一种格式符合C和C++的习惯。声明一个数组后,只拥有对数组的一个引用,为了给数组创建对应的存储空间,还需要初始化数组。
数组中的概念
元素:存储在数组中的数据;
长度:length表示数组能存多少个数据,是数组的大小,不是实际元素的个数;
索引:(下标、角标)每一个数据的编号,其范围是[0,arr.length-1];
2 数组的初始化
数组初始化方法
数组初始化有两种方式,静态初始化和动态初始化。静态初始化无需指定数组长度,直接赋值;动态初始化需要指定数组长度。
1.静态初始化
int[] arr1 = new int[]{1,2,3,4,5}; // 方式一
int[] arr2 = {1,2,3,4,5}; // 方式二
int[] arr3; // 方式三
arr3 = new int[]{1,2,3,4,5};
2.动态初始化
int[] arr1 = new int[5]; // 创建数组长度为5的数组方式一
int[] arr2; // 创建数组长度为5的数组方式二
arr2 = new int[5];
// 向数组中放入数据
arr1[0] = 1;
arr1[1] = 2;
...
数组元素初始化值
数组的数据类型可以是基本数据类型,也可以是对象。数组元素的自动初始化值由数据类型决定,如果是数值型,初始化为0;如果是字符型,初始化为空;如果是布尔型,初始化为false;如果是引用类型,初始化为null。
public class Arr{
public static void main(String[] args) {
int[] a = new int[3];
char[] b = new char[3];
boolean[] c = new boolean[3];
String[] d = new String[3];
System.out.println("a:"+Arrays.toString(a));// [0, 0, 0]
System.out.println("b:"+Arrays.toString(b));// [ , , ]
System.out.println("c:"+Arrays.toString(c));// [false, false, false]
System.out.println("d:"+Arrays.toString(d));// [null, null, null]
}
}
3 动态创建数组的内存分析
int[] arr = new int[5];
JVM中内存划分:堆中存放对象new int[5],栈中存放变量arr。
0x123为堆地址,将地址存入栈中,动态数组创建后,系统会分配默认值0。
数组参数传递机制
public class Arr{
public static void main(String[] args) {
// 动态初始化arr1
int[] arr1 = new int[5];
arr1[0] = 1;
arr1[1] = 2;
System.out.println(Arrays.toString(arr1)); // [1, 2, 0, 0, 0]
// 将第arr1的引用赋给arr2
int[] arr2 = arr1;
arr2[0] = 3;
arr2[1] = 4;
System.out.println(Arrays.toString(arr1)); // [3, 4, 0, 0, 0]
}
}
将arr1的地址0x123赋给arr2,这样arr2就可以访问0x123数组中的对象,如果arr2修改了数组中的对象,arr1中数组对象同样改变。
4 二维数组
二维数组:数组中每个元素都是一维数组。
动态初始化二位数组:
int[][] arr = new int[3][4];
System.out.println(arr.length); // 3
System.out.println(arr[0]); // 存放第一个一维数组的地址,若未定内层数组长度,则为null
// Arrays.deepToString可以将多维数组转化为String
System.out.println(Arrays.deepToString(arr));// [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Arrays.deepToString()方法可以将多维数组转换为多个String。
5 循环遍历数组
一维数组
int[] arr = new int[] { 1, 2, 3, 4, 5 };
for (int i = 0; i < arr.length; i++) { // 循环遍历数组中的值
System.out.println(arr[i]); // 打印 arr[i] 1 2 3 4 5
}
二维数组
// 使用三个一维数组拼装成一个二位数组
int[][] arr = new int[][] { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 } };
for (int i = 0; i < arr.length; i++) { // 遍历外层数组元素
for (int j = 0; j < arr[i].length; j++) { // 遍历内层元素
System.out.println(arr[i][j]); // 打印时需指定到外层,内层索引
}
}
增强for循环(foreach)
foreach用于遍历数组和集合
循环结构:
for (元素数组类型 自定变量名: 数组对象或集合对象){
循环体
}
示例:
int[][] arr = { { 1, 2, 3 }, { 3, 4, 5 }, { 5, 6, 7 } };
for (int[] temp : arr) { // 外层
for (int value : temp) { // 内层
System.out.println(value);
}
}
6 Arrays工具类
java.util.Arrays中有一套数组的static方法:
1.equals():用于比较两个数组是否相等;
2.fill():用于在数组中填充相同的测试数据;
3.sort():用于对数组排序;
4.binarysearch():用于在已排序的数组中查找元素;
5.toString():返回内容的字符串表示(多维数组用deepToString);
6.hashCode():产生数组的hashCode值;
7.asList():可以将任意序列或数组转换成List容器。
public class Arrays_Use {
public static void main(String[] args) {
int[] arr1 = { 1, 24, 20, 12, 7, 5 };
int[] arr2 = { 24, 1, 20, 12, 5, 7 };
// equals()比较
System.out.println(arr1.equals(arr2));// fasle
// fill()填充
int[] arr3 = new int[5];
Arrays.fill(arr3, 1);
System.out.println(Arrays.toString(arr3));// [1, 1, 1, 1, 1]
// sort()排序
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1)); // [1, 5, 7, 12, 20, 24]
// binarySearch()搜索
int index = Arrays.binarySearch(arr1, 7);
System.out.println(index);// 2
// hashCode()值
System.out.println(arr1.hashCode());// 1599496431
// asList()转换为集合
List<int[]> list = Arrays.asList(arr1);
}
}
7 toString分析
自定义一个方法,实现toString的功能,其原理是循环遍历出数组的元素后,拼接为一个String字符串。
public class ToString {
public static void main(String[] args) {
int[] ages = new int[] { 19, 20, 30 };
String s = toString(ages); // 调用方法并接收值,定义String变量接收
System.out.println(s); // [19,20,30]
}
// 自定义toString方法
public static String toString(int[] arr) { // 将传入的数据转成字符串返回给调用者
String str = "["; // 定义一个字符串"["
for (int i = 0; i < arr.length; i++) { // 在数组内部做循环
if (i != arr.length - 1) {
str += arr[i] + ","; // 若不为最后一个数,加",",并加在字符串中
} else {
str += arr[i] + "]"; // 最后一个数加"]",然后拼接
}
}
return str; // 返回值为字符串,调用者需定义一个字符串变量接收返回值
}
}
8 冒泡排序
对数组中各元素从头到尾比较相邻的两个元素大小,若左边大于右边,则交换位置。
public class BubbleSort {
public static void main(String[] args) {
int[] num = { 4, 5, 1, 3, 6, 2 };
bubbleSort(num); // 调用排序方法
for (int a : num) { // 对排序后的数组遍历然后打印
System.out.println(a);
}
}
// 排序方法
public static void bubbleSort(int[] arr) {
for (int i = 1; i < arr.length; i++) { // 轮次length-1轮
for (int j = 0; j < arr.length - 1; j++) { // 每轮比较次数length-轮次
if (arr[j] > arr[j + 1]) { // 如果左边的数>右边的数,交换位置
int temp;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
9 binarysearch二分搜索法
将需要查找的元素与数组的中间元素比较,根据大小逐渐向目标方向靠拢。
public class BinarySearch {
public static void main(String[] args) {
int[] a = { 1, 4, 7, 34, 66, 77, 89, 123 }; // 二分搜索前需排好序
int b = binarySearch(77, a);
System.out.println(b);
}
public static int binarySearch(int ele, int[] arr) { // ele为需要搜索的元素
int minIndex = 0;// 最小索引 0
int maxIndex = arr.length - 1;// 最大索引 7
int midIndex = (minIndex + maxIndex) / 2;// 中间位置 3
while (minIndex <= maxIndex) {
if (arr[midIndex] > ele) { // 如果ele<arr[midIndex]中间元素,向左移一位
maxIndex = midIndex - 1;
} else if (arr[midIndex] < ele) { // 如果ele>arr[midIndex]中间元素,向右移一位
minIndex = midIndex + 1;
} else {
return midIndex; // 返回值为索引
}
midIndex = (minIndex + maxIndex) / 2; // 重新计算midIndex的值
}
return -1;
}
}
10 数组的复制
在System中有一个arraycopy()的方法,可以复制数组中的元素,但是两个数组的类型要一致。
System.arraycopy(src, srcPos, dest, destPos, length);
src:源数组;
srcPos:源数组起始索引;
dest:目标数组;
destPos:目标数组起始索引;
length:复制长度;
int[] arr1 = { 1, 3, 5, 7, 9};
int[] arr2 = new int[8];
// 源数组为arr1,复制起始索引为1,目标数组为arr2,起始索引为3,复制长度为3
System.arraycopy(arr1, 1, arr2 , 3, 3);
System.out.println(Arrays.toString(arr2));// [0, 0, 0, 3, 5, 7, 0, 0]
11 可变参数
格式
返回值类型 方法名(参数类型…形参){}
例如int…arr 表示一个可变参数,将参数当作一个数组使用,这个参数可以接受0个或则n个int类型的数据,也可以接受int类型一维数组,等价于int[] arr。
一个方法中可以同时有可变参数和普通参数,可变参数放列表最后。
public class Arrays {
public static void main(String[] args) {
int[] arr1 = { 1, 2, 3 };
int ret = getSum(arr1); // 等价于getSum(1,2,3)
System.out.println(ret);
}
public static int getSum(int... arr) {
int sum = 0;
for (int e : arr) {
sum += e;// 将数组中的数据累加
}
return sum;// 结果为6
}
}