数组是一个固定长度的,包含了相同类型数据的容器
数据类型[ ] 数组名; // 声明一个数组
例如:
int[] array1; // 声明数组array1
初始化,就是在内存中为数组开辟空间,并将数据存入容器的过程
完整格式:
数据类型[ ] 数组名 = new 数组名[ ]{ value1,value2,……};
eg. int[ ] arr = new arr[ ] {1,2,3};
日常使用中,更倾向于简化格式:
数据类型[ ] 数组名 = { value1,value2,……};
eg. int[ ] arr = {1,2,3};
更多例子:
double[] arr1 = {1.2,2.3,4.5 };
String arr2 = {"hello","world"};
初始化时只指定数组长度,由系统为数组分配初始值。
数据类型[ ] 数组名 = new 数据类型[ 数组长度 ]
eg. int[ ] array = new int[10];
例如:
public class HelloWorld {
public static void main(String[] args) {
double[] array = new double[10] // 创建一个长度为10的数组
array[0] = 3.4;
array[1] = 5.8;
System.out.println(array[0]); // 3.4
System.out.println(array[1]); // 5.8
// 没有手动赋值,系统自动为其赋值(默认)
System.out.println(array[2]); // 0.0
}
}
用for循环基本可以搞定大部分操作;
增强for循环(for-each):
for(type element: array)
{
System.out.println(element);
}
说到读取元素,不得不提数组在计算机中的内存。
对于数组而言,计算机会在内存中为其申请一段连续的空间,并且会记下索引为 0 处的内存地址。以数组 [“C”, “O”, “D”, “E”, “R”] 为例,它的各元素对应的索引及内存地址如下图所示:
一旦知道了内存地址就可以立即访问到该元素,因此它的时间复杂度是常数级别O(1)。
总之:
这里就是我们经常说的暴力搜索,从头开始搜索;当然最典型的改进就是二分查找。
正是因为数组的在内存空间的地址是连续的,所以在插入元素的时候,就很大可能要 移动 其他元素的地址。
如果是在数组的结尾插入元素,那比较方便。即计算机通过数组的长度和位置计算出即将插入元素的内存地址,然后将该元素插入到指定位置即可。
但如果是想在将该元素插入到数组中的其他位置,这时首先需要为该元素所要插入的位置腾出空间,然后进行插入操作。
删除元素与插入元素的操作类似;
当删除掉数组中的某个元素后,数组中会留下 空缺 的位置,而数组中的元素在内存中是连续的,这就使得后面的元素需对该位置进行 填补 操作;
即 数组的元素是不能删的,只能覆盖。
只要记住:
方法在传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实参的值
方法在传递引用数据类型时,传递的是地址值,形参的改变,影响实参的值
所以数组作为引用类型,在作为形参时,要注意它是否被改变
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
printArray(new int[]{3, 1, 2, 6, 4, 2})
总之:
当两个数组指向同一个空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改后的结果了
二维数组的本质上仍然是一个一维数组,只是将数组中的每个元素变成了一维数组。
内部的一维数组仍然从索引 0 开始。
与一维数组一样,二维数组同样会在内存中申请一段 连续 的空间,并记录第一行数组的索引位置,即 A[0][0]
的内存地址,如图:
定义:
int[][] a=new int[5][5];
String[][] b=new String[3][4];
初始化:
//静态初始化
int[][] a={{1,2,3},{4,5,6,7},{8,9,10,11}};
//动态初始化
String[][] b=new String[10][10];
b[0]=new String[]{"zahngsan","lisi","wangwu"};
b[1]=new String[]{"java","python","c++"};
public static void main(String[] args) {
//静态初始化
int[][] a={{1,2,3,4},{4,5,6,7},{8,9,10,11}};
//调用print方法
print(a);
}
public static void print(int[][] a){
//遍历
// a.length为 3,a[0].length为 4
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j]+" ");
}
System.out.println();
}
}
java.util.Arrays
类能方便地操作数组
直接看方法:
方法 | 含义 |
---|---|
String toString(数组) | 把数组拼接成一个字符串 |
int [ ] copyOf(原数组,新数组长度) | 拷贝数组 |
int [ ] copyOfRange(原数组,起始索引,结束索引) | 拷贝数组(指定范围),左闭右开 |
void fill(int[ ] a, int val) | 填充数组,将指定的 val 值分配给数组a指定范围中的每个元素 |
boolean equals(long[ ] a, long[ ] a2) | 如果两个数组以相同顺序包含相同的元素,则两个数组是相等的 |
void sort(Object[ ] a) | 对指定对象数组根据其元素的自然顺序进行升序排列 |
void sort(类型[] a, Comparator super T> c) | 使用比较器对象自定义排序 |
int binarySearch(Object[ ] a, Object key) | 用二分查找算法在给定数组中搜索给定值的对象(Byt(在调用前必须排序好) |
看几个示例熟悉用法
e.g.1
int[] a={1,5,7,2,4,9};
// 将数组转化为字符串输出
String str=Arrays.toString(a);
System.out.println("字符串:"+str);
// 拷贝操作,新数组长度是5,从原数组第一个元素开始
int[] dp = Arrays.copyOf(a,5);
System.out.println("拷贝后数组是:"+Arrays.toString(dp)); // 拷贝后数组是:[1, 5, 7, 2, 4]
// 拷贝操作,拷贝原数组下标从1-5(不含)
int[] db = Arrays.copyOfRange(a,1,5);
System.out.println("拷贝后数组是:"+Arrays.toString(db)); // 拷贝后数组是:[5, 7, 2, 4]
//所有元素都赋值成特定值
Arrays.fill(a,10);
System.out.println("赋值后:"+Arrays.toString(a));
输出:
字符串:[1, 5, 7, 2, 4, 9]
拷贝后数组是:[1, 5, 7, 2, 4]
拷贝后数组是:[5, 7, 2, 4]
赋值后:[10, 10, 10, 10, 10, 10]
eg2 排序
再说一下排序,分为自然排序和自定义排序
自定义排序 void sort(类型[] a, Comparator super T> c)
设置 Comparator接口 对应的比较器对象,来定制比较规则
// 1、默认升序排序
int[] ages = {34,12,42,23};
Arrays.sort(ages);
System.out.println(Arrays.toString(ages));
// 2、自定义比较器对象,只能支持引用类型的排序!
Integer[] ages1 = {34,12,42,23};
/*
参数一:被排序的数组必须是引用类型的元素
参数二:匿名内部类对象,代表了一个比较器对象。
*/
Arrays.sort(ages1,new Comparator<Integer>( ) {
@Override
public int compare(Integer o1,Integer o2) {
// 降序排列
return o2-o1;
// 升序排序即 return o1-o2;
}
});
System.out.println(Arrays.toString(ages1));
输出:
[12, 23, 34, 42]
[42, 34, 23, 12]
当然,自定义排序还可以对 对象 进行排序,比如按照对象的某一属性
如可以自己定义一个学生类,按照学生的身高排序
Student[] students = new student[3];
students[0] = new Student( name: "张三" ,age: 23 , height: 172);
students[1] = new student( name: "李四",age: 19 , height: 187);
students[2] = new student( name: "王五",age: 22 ,height:178);
system.out.println(Arrays.toString(students));
// Arrays.sort(students); 直接排序会报错
Arrays.sort(students, new Comparator<Student>() {
@0verride
public int compare(Student o1,Student o2){
//自己指定比较规则
return o1.getAge() - o2.getAge(; //按照年龄升序排序!}
});
System.out.println(Arrays.toString(students));
参考链接:
https://leetcode.cn/leetbook/read/array-and-string/yjcir/
https://www.runoob.com/java/java-array.html