数组
文章目录
一、什么是数组
-
程序 = 算法 + 数据结构
-
数据结构:就是把数据按照某种特定的结构保存,设计一个合理的数据结构是解决问题的关键。
-
数组:最基本的数据结构
-
数组的特定结构:!相同类型组成元素的“集合”
-
通过元素的下标进行访问 ,下标从0开始,最大元素下标为[数组长度-1]。
二、数组定义
-
数据类型[] 数组名 = new 数据类型[数组长度];
int[] arr = new int[5]; 含义: int:数组的元素类型必须为int new:创建了一个新对象 5:数组的长度 初始值为int的默认值 元素初始值为{0,0,0,0,0}
数组是一个线性存储:每一个元素都有前继元素(第一个元素没有前继元素)和后继元素(最后一个元素没有后继元素)
三、数组初始化
1、基本数据类型数组默认元素值为
- 整型:0
- 浮点行:0.0
- 字符型:空字符
- 布尔型:false
2、三种初始化方式
//第一种方式: 数据类型[] 数组名称 = new 数据类型[数组长度];
int[] arr = new int[5];// <==> int arr[] = new int[5];
//第二种方式:数据类型[] 数组名称 = new 数据类型[数组长度]{数组元素值};
int[] arr = new int[]{1,2,3,4,5};
//第三种方式
int[] arr = {1,2,3,4,5};
/**
* 1.这种写法只能在声明时就赋值,不能定义后在赋值
* 2.int[] arr; arr = {1,2,3,4,5};编译错误,对于数组的赋值只能对其元素赋值,不能对于数组定义进行赋值。
* 3.可以采取第二种方法,声明后在赋值。
*/
四、数组访问
1、通过下标访问数组元素
/**
* 1、数组访问
* 通过下标访问
* 获取下标长度length
*/
int [] arr1 = {1,3,5,7,9};
arr1[1] = 6;//把第二元素3重新赋值为了 6 ->数组元素下标是从0开始的;
System.out.println("arr" + Arrays.toString(arr1));//arr[1, 6, 5, 7, 9]
//toString 返回字符串,数组是在Arrays类里面有一个toString()重写的方法;
System.out.println(arr1.length);//5 length获取下标长度
2、遍历数组元素
基本for循环
/**
* 循环遍历
* 1、基本for
*/
int[] arr2 = new int[10];//声明一个int类型数组有十个内存空间
//把所有值赋值为5
for(int i = 0;i < arr2.length;i++){
arr2[i] = 5;
}
System.out.println("arr2" + Arrays.toString(arr2));//arr2[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
增强for循环
/**
* jdk1.8提供了数组使用增强for
*/
int[] arr3 = new int[10];
//本来是想把arr3的所有值全部赋值为7,结果error
for(int temp : arr3){
temp = 7;
}
System.out.println("arr3" + Arrays.toString(arr3));//arr3[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
//使用增强for打印
int[] arr4 = new int[]{0,1,2,3,4,5,6,7,8,10};
for(int temp : arr4){
System.out.print(temp + " ");//循环输出后的效果 0 1 2 3 4 5 6 7 8 10
}
总:这里我开始准备遍历赋值计算的,结果发现根本没有改变原来的值,我反编译去查看了发现了,增强for在数组使用时是将他转为普通for把值赋值给变量,所以增强for在数组中不能改变原数组的值,(所以我发现增强for在数组中使用时,只是作为一个标本存在,并不能引用数组)
增强for在数组中和在集合中的区别
/**
* 1、增强for底层是迭代器
* 2、数组是特殊的集合,不是Collection继承关系中的
* 3、数组使用增强for编译时是转换为了普通for,所以实则还是使用的普通for
* 4、增强for循环在迭代集合时用的迭代器
*/
//数组
int[] arr4 = new int[]{0,1,2,3,4,5,6,7,8,10};
for(int temp : arr4){
System.out.print(temp + " ");//循环输出后的效果 0 1 2 3 4 5 6 7 8 10
}
System.out.println();
//集合
List<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (Integer temp : arrayList){
System.out.print(temp + " ");//1 2 3
}
总:的确增强for底层使用的时迭代,数组不是使用的增强for只是一个用法形式并不是所谓真正的增强for。
实例
/**
* 产生十个0-100的10个随机数存储
*/
int[] arr1 = new int[10];
for (int i = 0; i < arr1.length ; i++) {
arr1[i] = (int)(Math.random()*100);//Math.random(),随机生产0-1的随机数。
}
System.out.println(Arrays.toString(arr1));//每次输出都是随机数
}
五、数组复制
/**
* 1.System.arrayCopy()方法
*java.lang.System //所在包
* public static void arraycopy(@NotNull Object src,//原数组
* int srcPos,//原数组起始坐标
* @NotNull Object dest,//目的数组
* int destPos,//目标起始位置
* int length)//复制的长度
*/
int arr1[] = {1,2,3,4,5};
int arr2[] = new int[4];
System.arraycopy(arr1,0,arr2,1,3);//把arr1从下标0开始复制到arr2下标1依次复制3个元素。
System.out.println("arr2" + Arrays.toString(arr2));//arr2[0, 1, 2, 3, 4],说明了数组一旦创建元素个数就不能改变了。
/**
* 2、Arrays.copyOf
* 当复制内容小于时截取
* 当复制内容大于时扩展
*
* !!!那数据长度变化了吗?变了,但不是原数组长度变了而是重新创建了个新数组;
*/
int[] arr3 = {1,2,3,4,5};
System.out.println("复制前长度:" + arr3.length);//5
arr3 = Arrays.copyOf(arr3,7);
System.out.println("复制后长度:" + arr3.length);//7
System.out.println("arr3" + Arrays.toString(arr3));//arr3[1, 2, 3, 4, 5, 0, 0]
Arrays.copyOf编译过后的源码反编译:
**总:**所以真正意义上数组复制只有一个System.arrayCopy(),因为Arrays.copyOf()也是使用的System.arrayCopy()复制。
六、数组排序
1.数组的排序(深究)
- 排序是最常见的算法之一。
- 排序: 将数组元素按照从小到大或者从大到小的顺序排列。
- 常见的排序算法:冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序等。
冒泡排序法:
/**
* 冒泡排序,把未排序的数组最小(降序)或最大(升序)往最后推
* 把{1,2,3,4,5,8,6,10,9,7}倒序排列
*/
int[] arr = {1,2,3,4,5,8,6,10,9,7};
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10 - i - 1; j++) {//每一次把未排序的最小的一个放在未排序的最后一个
int temp;
//交换元素
if(arr[j] < arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
System.out.print("第" + (i+1) + "个数排序的第" + (j+1) +"次排序" + Arrays.toString(arr) + " ");//显示每次执行的结果顺序
}
System.out.println();
}
System.out.println("排序后:" + Arrays.toString(arr));//排序后:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
}
**总:**其实我理解的冒泡排序就是像那个鱼冒泡一样把数字往后面推。
- Arrays.sort方法
/**
* Arrays.sort方法
*/
int[] arr2 = {10,2,5,7,4,2,1,5,3};
Arrays.sort(arr2);//默认升序
System.out.println("排序后:" + Arrays.toString(arr2));//排序后:[1, 2, 2, 3, 4, 5, 5, 7, 10]
- sort方法原理:
参考:https://www.cnblogs.com/baichunyu/p/11935995.html
案例
/**
* 1.随机产生一个长度为20的数组(整数0-200)
*/
int[] array = new int[20];
for (int i = 0; i < array.length; i++) {
array[i] = (int) (Math.random() * 200);//随机生成一个0-200的整数
}
System.out.println("随机生成的数:" + Arrays.toString(array));
/**
* 2.不采用排序方式找到最大值
*/
int max = array[0];//把第一个看做最大的
int k = 0;//最大元素下标
for (int i = 0; i < array.length; i++) {
if(array[i] > max){//如果数组比max大就把大的放在max中
max = array[i];
k = i;
}
}
System.out.println("最大值为:" + max);
/**
* 3.将最大值和最后一个元素替换
*/
{
int temp = array[k];
array[k] = array[array.length - 1];//把最元素和最后一个元素替换,下标等于字符长度-1
array[array.length -1] = temp;
}
/**
* 4.删除最后一个元素-->最大值
*/
array = Arrays.copyOf(array,array.length-1);
System.out.println("删除最大值后的为:" + Arrays.toString(array));
/**
* 5.正序输出
*/
Arrays.sort(array);
System.out.println("正序排序后:" + Arrays.toString(array));
/**
* 6.逆序输出
*/
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i -1; j++) {
if(array[j] < array[j+1]){
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
System.out.println("逆序排序后:" + Arrays.toString(array));