数组
- 可以存放多个同一类型的数据。数组是一种数据类型,也是引用类型。
- 数据类型 数组名[](这里的这个中括号也可以写在数据类型后面)=new 数据类型[大小]。例:int a[] = new int [5];//创建了一个数组,名字为a,存放5个int。
- 与上面一条不同的另外一种动态分配数组的方式:先声明数组,再存放数据(new)。例:double scores[] ;scores = new double[5];
- 静态初始化:数据类型 数组名[]={元素值,元素值...}
- 数组的引用(使用/访问/获取...数组都是一个意思):数组名[下标/索引]。
细节:
- 数组创建后,如果没有赋值,有默认值。int、short、byte、long都是0,float、double是0.0,char是\u0000,boolean是false,String是null。
- 数组的下标是从0开始的。且数组的下标要在指定范围内使用,否则会报下标越界异常。
数组赋值机制
- 基本数据类型赋值不会相互影响。如int n1 = 2;int n2 = n1;把n1的值赋给n2并不会影响n1,n2发生变化也不会影响到n1,他们的赋值方式是简单的值传递(值拷贝)。
- 数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用传递(地址拷贝)。如int[] arr1 ={1,2,3};int [] arr2 = arr1;这里arr2如果发生变化,arr1也会随之改变。
数组拷贝
如何实现对数组内容的赋值,且数据空间是独立的?
创建一个新的数组arr2,开辟新的数据空间:
int[] arr1 = {10,20,30};
int[] arr2 = new int[arr1.length];//创建新的数组开辟新的数据空间
//遍历arr1,把每个元素拷贝到对应的元素的位置
for(int i = 0; i < arr1.length; i++){
arr2[i] = arr1[i]
}
此时对arr2再进行修改就不会对arr1有影响。
数组反转
把一个数组里的数据顺序反转:方法1:
int temp = 0;
int len = arr.length;
for( int i = 0;i < len / 2;i++){
temp = arr[len -1 -i];
arr[len -1 -i] = arr[i];
arr[i] = temp;
}
方法2:
//使用逆序赋值的方法,创建一个新的数组,逆序遍历原数组再拷贝到新数组中
int[] arr = {11,22,33,44,55};
int[] arr2 = new int[arr.length];
for(int i = arr.length - 1;i >= 0; i--){
arr2[arr.length-i-1] = arr[i]
}
数组添加
实现动态的给数组添加元素效果,实现对数组扩容。
- 定义一个新的数组:int[] arrNew = new int[arr.length+1]
- 遍历原来的数组,依次将arr的元素拷贝到arrNew数组
- 再将新添加的数组赋给arrNew最后一个元素
- 让ar指向arrNew那么原来的数组就被销毁了
public class Array03 { public static void main(String[] args) { int[] arr = {1,2,3}; int[] arr2 = new int[arr.length + 1]; for(int i = 0;i < arr.length; i++){ arr2[i] = arr[i]; } arr2[arr2.length - 1] = 4; arr = arr2; for(int i = 0;i < arr2.length; i++){ System.out.print(arr2[i]); } } }
数组排序
- 内部排序:将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法);
- 外部排序:数据量过大,无法加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
- 冒泡排序:如图所示
代码实现:
public class Paixu01 {
public static void main(String[] args) {
int[] arr = {12,82,23,14,45};
int temp = 0;//用于辅助交换的变量
for(int i = arr.length ; i > 0;i--){
for(int j = 0 ; j < i-1 ; j++){
if(arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];//把小的值先换到前面
arr[j+1] = temp;//再把大的值放到后面
}
}}for(int i = 0;i < arr.length ;i++){
System.out.print(arr[i]+"\t");
}
}
}
查找
也是属于遍历数组,逐一比较
多维数组-二维数组
两个中括号:int[] [] arr=....就是二维数组,用arr[i].length来表示二维数组中第i个元素(一维数组)的长度
int[][] arr = {{0,0,0,0},
{1,1,1,1},
{2,2,2,2},
{3,3,3,3}
};
for(int i = 0; i < arr.length; i++){//遍历二维数组每一个元素(一维数组)
for(int j = 0; j < arr[i].length; j++{//对每个一维数组的遍历
System.out.print(arr[i][j] + " ");//分别打印每一个一维数组的元素
}
System.out.println();//换行
}
二维数组的动态赋值方法和一维数组类似,只不过需要记住写两个中括号。
二维数组进行赋值时,先指向其中的元素地址,也就是一维数组的地址,然后一维数组再指向各自的地址再改变元素数值,遵循一维数组引用传递的规则。
动态初始化:
- 先声明,再定义数组名开辟空间,再赋值:
int arr[][]; arr = new int[2][3];
- 列数不确定,即每个一维数组的个数可以不一样,赋值的时候可以只确定一维数组的个数如:int[][] arr = new int[3][];每个一维数组还没有开辟数据空间:
int[][] arr = new int[3][];//此时只确定了一维数组的个数,每个一维数组里面存放的应为null for(int i = 0; i < arr.length; i++){ arr[i] = new int[i+1];//确定一维数组的元素个数,为每个元素开辟空间 for(int j = 0; j < arr[i].length; j++){ arr[i][j] = i + 1;//赋值 } } for(int i= 0; i < arr.length; i++){//遍历arr输出 for(int j = 0; j < arr[i].length; j++){//输出每个一维数组 System.out.print(arr[i][j] + " "); }System.out.println();//换行 }
输出的二维数组是这样的:,可以修改代码中一维数组的个数继续打印。
静态初始化:直接赋值:类型 数组名[][]={{值1,值2...},{值1,值2...},{值1,值2.....}}
二维数组经典应用案例-杨辉三角
例题:使用二维数组打印一个10行杨辉三角,(要注意观察杨辉三角的规律得出,每一行的第一列与最后一列都是1,中间的值都等于上一行的同一列与上一行的前一列的数之和)
public class Array201 {
public static void main(String[] args) {
int yanghui[][]= new int[10][];
for(int i = 0; i < yanghui.length; i++){
yanghui[i] = new int[i+1];//分配每一行的元素个数
for(int j = 0; j < yanghui[i].length; j++){
if(j ==0 || j == yanghui[i].length-1){//第一列和最后一列的元素为1
yanghui[i][j]=1;
}else{
yanghui[i][j]=yanghui[i-1][j] + yanghui[i-1][j-1];
}
}
}
for(int i = 0; i < yanghui.length; i++){
for(int j = 0; j < yanghui[i].length; j++){
System.out.print(yanghui[i][j]+" ");
}
System.out.println();
}
}
}
注意:
//声明
int[] x,y[];
//这句话声明了两个数组x和y,但是x是一维整数数组,y是一个二位整数数组
//等价于
int[] x;
int[][] y;