1.数组的概念
1.1 什么是数组
1.存储相同类型的数据
2.数据在内存中连续存储
3.存放的是多个数据
对数组的理解:定义一个数组相当于一次定义了多个变量
1.2 什么是数组元素
构成数组的每一个数据就称为数组的元素
1.3 什么是数组下标
数组的下标就是元素在数组中的位置,下标从0开始,依次累加1
数组下标的界限是: 0 ~ 数组长度-1
数组的下标也可以称为:索引
如果数组下标 <0 或 >数组长度-1 控制台抛出异常(ArraysIndexOutOfBounds)
1.4 什么是数组长度
数组长度就是数组的大小
也就是数组元素的个数
获取数组的长度的方法:数组名 .length
注:数组的大小在为其元素分配内存大小时就已经确定,大小不可改变
2. 数组的声明和创建(以一维数组为例)
2.1 定义数组
数据类型 数组名[];
//数组名在前
int arr1[];
//数组名在后
int[] arr2;
2.2 为数组元素分配内存空间
数据类型 数组名[] = new 数据类型[ 数组大小 ]; //数据类型必须相同,new运算符就是为数组元素分内存
//一种方法
int arr1[] = new int[5];
//另一种方法
double[] arr2;
arr2 = new double[4];
2.3 数组元素初始化
//第一种写法
int arr1[] = new int[]{1, 2, 3, 4, 5};//int[]中括号内不可以写数组的大小
//第二种写法
int arr2[] = {1, 2, 3}
//第三种写法
double[] arr3;
arr3 = new double[]{1.0, 2.1, 3.2, 4.4};
//第四种写法
char []ch4 = new char[4];
ch4[0] = 'v';
ch4[1] = 'h';
ch4[2] = 'n';
ch4[3] = 'm';//这种写法数组的下标一定不能发生越界,即超出数组的大小范围
2.4 为数组元素分配内存时,数组元素在内存中的表现形式
int [] score = new int[5]
此时score中存放的值是一个引用类型的值:0xAA01,这个值是一个指针,指向内存中首地址为 0xAA01 长度为5的一块连续内存,由于没有对素组元素初始化,所以默认值为 0.
3. 数组的使用
3.1 找数组元素的最大(小)值,求总和,求平均
public static void main(String[] args){
int [] arr = new int[]{23, 34, 54, 13, 45} ;
int max = arr[0];
int min = arr[0];
int sum = 0;
for(int i = 1; i < arr.length; i++){
if(max < arr[i]){
max = arr[i];
}
if(min > arr[i]){
min = arr[i];
}
sum +=arr[i]
}
System.out.println("最大值为:" + max);
System.out.println("最小值为:" + min);
System.out.println("总和为:" + sum);
System.out.println("平均值为:" + sum/arr.length);
}
3.2 对数组排序
3.2.1 冒泡排序
public static void main(String[] args) {
int score[] = new int[80000];
Random random = new Random();//设计一个随机数
for (int i = 0; i < score.length; i++) {
score[i] = random.nextInt(80000);//对数组元素通过随机数进行初始化
}
long start = System.currentTimeMillis();//记录程序进行到这步的时刻
//冒泡排序
for (int i = 0; i < score.length-1; i++) {
for (int j = 0; j < score.length-i-1; j++) {
if(score[j]>score[j+1]){
int tmp = score[j];
score[j]=score[j+1];
score[j+1]= tmp;
}
}
}
long end = System.currentTimeMillis();//程序排序完成进行到这步的时刻
System.out.println(end-start);//计算冒泡排序从开始到结束的时间
/*for (int i = 0; i < score.length; i++) {
System.out.println(score[i]);
}*/
}
结果:80000个数使用冒泡排序大约用时8450毫秒(不同电脑得到的结果不同,和电脑性能有关)
3.2.2 选择排序
public static void main(String[] args) {
int[] arr = new int[80000];
Random r = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = r.nextInt(80000);
}
long start = System.currentTimeMillis();
//选择排序
for (int i = 0; i < arr.length-1; i++) {//每次循环都会找出最小的数
int minIndex = i;//记录最小数的下标
int min = arr[i];//记录最小数
for(int j = i+1; j < arr.length; j++){//每次循环都会找出最小的数
if (arr[j] < min){//如果当前数比最小数小,则更新最小数
min = arr[j];//更新最小数
minIndex = j;//更新最小数的下标
}
}
int tmp = arr[i];
arr[i] = arr[minIndex];//将最小数放到最前面
arr[minIndex] = tmp;
}
long end = System.currentTimeMillis();
System.out.println(end-start);
System.out.println(Arrays.toString(arr));
}
结果:80000个数使用选择排序大约用时1800毫秒(不同电脑得到的结果不同,和电脑性能有关)
3.2.3 插入排序
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int)(Math.random() * 80000);
}
long start = System.currentTimeMillis();
//插入排序
for (int i = 1; i < arr.length; i++) {
int j = i;
while (j > 0){
if (arr[j] < arr[j-1]){
int temp ;
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
j--;
}else {
break;
}
}
}
long end = System.currentTimeMillis();
System.out.println(end -start);
}
结果:80000个数使用插入排序大约用时700毫秒(不同电脑得到的结果不同,和电脑性能有关)
3.2.4 快速排序
public static void main(String[] args){
//快排
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int)(Math.random() * 800000);
}
//打印开始排序时的时间
long s = System.currentTimeMillis();
quickSort(arr,0,arr.length-1);
//打印排序结束时的时间
long e = System.currentTimeMillis();
System.out.println(e-s);
}
public static void quickSort(int[] arr,int first,int last){
if (first >= last) {
return;
}
int low = first;
int high = last;
//如果mid_value = arr[last]的话,下面的两个内部while循环就要换一下顺序
int mid_value = arr[first];
while (low < high){
while (low < high && arr[high] >= mid_value){
high-=1;
}
arr[low] = arr[high];
while (low < high && arr[low] < mid_value){
low +=1;
}
arr[high] = arr[low];
}
arr[high] = mid_value;
//递归对左右两边的数据排序
quickSort(arr,first,low-1);
quickSort(arr,low+1,last);
}
结果:80000个数使用插入排序大约用时20毫秒(不同电脑得到的结果不同,和电脑性能有关)
4. Arrays类
4.1 什么是Arrays类
Arrays类是数组的工具类java.util.Arrays。
由于数组本身并没有什么方法可以供我们调用,但API中提供了一个工具类给我们使用,从而可以对数据对象进行一些基本的操作。
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而不用使用对象来调用。
4.2 常用方法
4.2.1 查找数组元素:通过binarySearch方法堆排序好的数组进行二分查找
public static void main(String[] args){
int []arr = new int[] {10,50,40,30 };
Arrays.sort(arr);//排序后 10 30 40 50 90
int index = Arrays.binarySearch(arr, 10);
System.out.println(index);
index = Arrays.binarySearch(arr, 0);
System.out.println(index);
index = Arrays.binarySearch(arr, 45);
System.out.println(index);
index = Arrays.binarySearch(arr, 90);
System.out.println(index);
}
结果:
0
-1
-4
-5
分析:
1.若找到了数据,则返回该数据的下标
2.若找不到数据,则返回负数,其值为该数据在数组中排序的位置
4.2.2 数组转字符串:Arrays.toString(array)
public static void main(String[] args){
int []arr1 = {10,50,40,30,89,67,4,678};
Arrays.sort(arr1);
System.out.println( Arrays.toString(arr1));
}
结果:
[4,10,30,40,50,67,89,678]
4.2.3 填充数组: Arrays.fill(array,val)
public static void main(String[] args){
int []arr1 = {10,50,40,30,89,67,4,678};
Arrays.fill(arr1,30);
System.out.println( Arrays.toString(arr1));
}
结果:
[30,30,30,30,30,30,30,30]
4.2.4 数组的比较:Arrays.equals(array1,array2)
public static void main(String[] args) {
int []arr1 = {10,50,40,30};
int []arr2 = {10,50,40,30};
int []arr3 = {60,50,85};
System.out.println(Arrays.equals(arr1, arr2));//判断arr1与arr2的长度及元素是否相等
System.out.println(Arrays.equals(arr1, arr3));//判断arr1与arr3的长度及元素是否相等
}
结果:
true
false
4.2.5 数组的排序:Arrays.sort(array)
4.2.5.1 数组全部排序
public static void main(String[] args){
int []arr1 = {10,50,40,30};
Arrays.sort(arr1);
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
}
结果:
[10,30,40,50]
4.3.5.2 指定数组下标排序
public static void main(String[] args){
int []arr1 = {10,50,40,30,89,67,4,678};
Arrays.sort(arr1,3,arr1.length-1);
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
}
结果:
[10,50,40,4,30,67,89,678]
4.2.6 数组的复制:Arrays.copyOf(array,length)
public static void main(String[] args){
int []arr1 = new int[] {10,50,40,30 };
//将arr1复制成长度为3的新数组arr2
int []arr2 = Arrays.copyOf(arr1,3);
System.out.println(Arrays.toString(arr2));
}
结果:
[10,50,40]
5. 多维数组(以二维数组为例)
5.1 定义数组
数据类型 数组名[][];
//数组名在前
int arr1[][];
//数组名在后
int[][] arr2;
5.2 为数组元素分配内存空间
数据类型[][] 数组名 = new 数据类型[ 数组第一阶长度 ][数组第二阶长度]; //数据类型必须相同,new运算符就是为数组元素分内存
//一种方法
int arr1[][] = new int[5][4];
//另一种方法
double[][] arr2;
arr2 = new double[5][4];
2.3 数组元素初始化
//第一种写法
int arr1[][] = new int[][] {{1,5},
{2,4,2} ,
{3,7,9,5} };//int[]中括号内不可以写数组的大小
//第二种写法
int arr2[][] ={{1,5},
{2,4,2} ,
{3,7,9,5} }
//第三种写法
double[][] arr3;
arr3 = new double[][] {{1.0,5.1},
{2.2,4.3,2.4} ,
{3.5,7.6,9.7,5.8} };
//第四种写法
char [][]ch4 = new char[3][2];
ch4[0][0] = 'v';
ch4[0][1] = 'h';
...
ch4[2][0] = 'h';
ch4[2][1] = 'm';//这种写法数组的下标一定不能发生越界,即超出数组的大小范围
通常在对二维数组进行操作时,一般都使用双重循环来处理。