*数组
1.数组基础概念
定义: 1.数组是相同类型数据的有序集合 2.每个数据称为一个数组元素,可以通过下标来访问每个数组元素 3.结构 ; (1). 变量类型[] 数组名;//声明一个数组 数组名=new 变量类型[数组长度];//定义一个数组 (2).变量类型[] 数组名=new 变量类型[数组长度];//声明并定义一个数组 5.数组名.length(用来获取数组长度) 6.数组的四个基本特点: (1)数组长度数确定的,一旦被创建其大小就不会再改变 (2)一个数组的元素必须是相同类型,不能混合 (3)数组元素类型可以是任何类型,包括基本类型和引用类型 (4)数组变量属于引用类型,数组也可以看成是对象,数组的每个元素相当于该对象的成员变量。数组本身就是对象,java中对象是在堆中的,因此数组不论是什么类型,数组对象本身是在堆中的。
package array; //数组 /* 定义: 1.数组是相同类型数据的有序集合 2.每个数据称为一个数组元素,可以通过下标来访问每个数组元素 3.结构 ; (1). 变量类型[] 数组名;//声明一个数组 数组名=new 变量类型[数组长度];//定义一个数组 (2).变量类型[] 数组名=new 变量类型[数组长度];//声明并定义一个数组 5.数组名.length(用来获取数组长度) 6.数组的四个基本特点: (1)数组长度数确定的,一旦被创建其大小就不会再改变 (2)一个数组的元素必须是相同类型,不能混合 (3)数组元素类型可以是任何类型,包括基本类型和引用类型 (4)数组变量属于引用类型,数组也可以看成是对象,数组的每个元素相当于该对象的成员变量。数组本身就是对象,java中对象是在堆中的,因此数组不论是什么类型,数组对象本身是在堆中的。 */ public class Demo01 { public static void main(String[] args) { int[] nums;//声明一个数组 nums =new int[10];//创建长度为10的一个数组 //可以直接这样写:int[] nums=new int[10]; nums[0]=1;//给数组元素赋值,int类型默认值为0,String默认值为空,没赋值就为默认值 nums[5]=5; nums[7]=7; nums[9]=9; System.out.println(nums.length);//数组名.length(用来获取数组长度) for(int i=0;i<nums.length;i++){ System.out.print(nums[i]+"\t"); } } }
2.数组的三种初始化和内存分析
数组三种初始化
1.静态初始化 int[] a={1,2,3,4,5,6};//数据类型[] 数组名={数组成员的值,...}
Man[] men={new Man(),new Man()};//应用类型的,Man代表一个类 2.动态初始化(包含了默认初始化:只要一创建,数组就会分配空间,每个数组成员都会有默认值) int[] a=new int[numbers]; a[0]=...; a[1]=...; ... a[numbers]=...;
3.数组的默认初始化:数组都是引用类型,他的元素相当于类的实例变量,因此数组一旦分配空间(被创建,不是声明),其中的每个数组元素也会按照实例变量同样的方式隐式初始化
数组内存分析
(1). 变量类型[] 数组名;//声明一个数组(此时内存在栈中) 数组名=new 变量类型[数组长度];//定义一个数组(此时内存在堆中,因为有new)
*(2).变量类型[] 数组名=new 变量类型[数组长度];//声明并定义一个数组,一般使用这种语句定义数组
package array; //数组三种初始化 /* 1.静态初始化 int[] a={1,2,3,4,5,6};//数据类型[] 数组名={数组成员的值,...} Man[] men={new Man(),new Man()};//应用类型的,Man代表一个类 2.动态初始化(包含了默认初始化:只要一创建,数组就会分配空间,每个数组成员都会有默认值) int[] a=new int[numbers]; a[0]=...; a[1]=...; ... a[numbers]=...; 3.数组的默认初始化:数组都是引用类型,他的元素相当于类的实例变量,因此数组一旦分配空间(被创建,不是声明),其中的每个数组元素也会按照实例变量同样的方式隐式初始化 */ public class Demo02 { public static void main(String[] args) { //静态初始化 int a[]={1,2,3,4}; System.out.println(a[0]); //动态初始化 int b[]=new int[10]; b[5]=5; //获取数组长度 int c=a.length; int d=b.length; System.out.println(b[5]); System.out.println(c); System.out.println(d); } }
3.数组边界与小结
1.数组合法边界:[0,length-1]
常见错误:
int[] array =new int[2]; System.out.println(array[2]);//发生越界 for(int i=0;i<=array.length;i++)//i<=array.length发生越界,不可等于,只能i<array.length { System.out.println(array[i]); }
会进行报错:ArrayIndexOutOfBoundsException
2.小结
(1)数组是相同数据类型的有序集合
(2)数组也是对象。数组元素相当于对象的成员变量
(3)数组长度是确定不变的,一旦越界就会报错:ArrayIndexOutOfBoundsException
4.数组的进阶使用
1.for-Each循环 //一般用来遍历数组元素打印输出 结构:for(int 变量名: 数组){ System.out.println(变量名); } 2.数组作方法的形参(如果要返回数组类型在定义方法时注意返回值类型要定义为数组类型,例如下面的int[])
public static int[] reverse(int[] array){}
3.数组作返回值 4.普通的for循环
package array; //数组的进阶使用 /* 1.for-Each循环 //一般用来遍历数组元素打印输出 结构:for(int 变量名: 数组){ System.out.println(变量名); } 2.数组作方法的形参 3.数组作返回值 4.普通的for循环 */ public class Demo03 { public static void main(String[] args) { int sum=0; int[] a={1,2,3,4,5}; System.out.println("数组的元素为"); for(int b:a){//for-Each循环 System.out.print(b+"\t"); } System.out.println(); System.out.println("==============================================================="); for(int i=0;i<a.length;i++){//普通for循环可以实现更多功能 sum+=a[i];//sum=sum+a[i] } System.out.println("数组元素和为"+sum); System.out.println("==============================================================="); printArray(a);//调用方法遍历数组并输出数组元素 System.out.println(); System.out.println("==============================================================="); int[] result=reverse(a);//创建一个新数组,并且使用reverse()方法赋予数组元素 System.out.print("反转后"); printArray(result); // 也可以不创建新数组直接调用两种方法打印printArray(reverse(a)); } //打印出数组元素 public static void printArray(int[] array){//数组作方法的形参 System.out.println("数组各元素打印出来为:"); for(int i=0;i<array.length;i++){ System.out.print(array[i]+"\t"); } } //数组元素进行反转 public static int[] reverse(int[] array){//注意这里的返回值类型为一种数组类型 int[] result=new int[array.length];//反转后数组长度自然与原数组长度相同 for(int i=0, j=array.length-1;i<array.length;i++,j--){ result[j]=array[i];//把原数组第一个元素赋值给新数组的最后一个元素 } return result; } }
5.多维数组
多维数组,相当于数组套数组,数组的元素也是一个数组,一般情况下二维数组就够用了
package array; //多维数组,相当于数组套数组,数组的元素也是一个数组,一般情况下二维数组就够用了 public class Demo04 { public static void main(String[] args) { int[][] array={{1,2},{3,4},{5,6}};//相当于一个[3][2]的数组 Demo03.printArray(array[1]);//调用Demo03的printArray()方法,由于这个方法只能遍历一维数组,所以选择遍历array[1]={3,4} System.out.println(); System.out.println("这个二维数组的元素打印出来为:"); for(int i=0;i< array.length;i++){//使用双层for循环就可以解决二维数组的遍历问题 for(int j=0;j<array[i].length;j++){ System.out.print(array[i][j]+"\t"); } } System.out.println(); System.out.println("==============================================================="); System.out.println("这个二维数组的元素打印出来为:"); int [][] arrays=new int[2][2];//动态创建二维数组 arrays[0][0]=1; arrays[0][1]=11; arrays[1][0]=111; arrays[1][1]=1111;//相当于int[][] arrays={{1,11,},{111,1111}}; for(int i=0;i< arrays.length;i++){ for(int j=0;j<arrays[i].length;j++){ System.out.print(arrays[i][j]+"\t"); } } System.out.println(); System.out.println("==============================================================="); System.out.println("这个三维数组的元素打印出来为:"); int[][][] arrayss={{{1,11},{111,1111}},{{11111,111111},{1111111,11111111}}}; for(int i=0;i< arrayss.length;i++){ for(int j=0;j<arrayss[i].length;j++){ for(int x=0;x<arrayss[i][j].length;x++) System.out.print(arrayss[i][j][x]+"\t"); } } } }
6.Arrays类
Arrays类,里面有很多关于数组的方法,比如排序,输出,比较数组元素等等,非常丰富 数组工具类java.util.Arrays: 1.由于数组本身没有什么方法可以供我们调用,但在API中提供了一个工具类Arrays供我们使用,可以对数组进行一些基本操作 2.Arrays类中的方法都是static修饰的,可以直接使用 类名进行调用,比如Arrays.toString() 3.常用功能:1.给数组赋值:fill() 2.对数组升序排序:sort() 3.比较数组元素是否相等:equal() 4.查找数组元素:binarySearch() 4.导入Arrays类后选中它然后 ctrl+左键 就可以看其源码,然后找到并点击左下角边界那里的Structure可以查看这个类有多少方法
package array; //Arrays类,里面有很多关于数组的方法,比如排序,输出,比较数组元素等等,非常丰富 import java.util.Arrays; /* 数组工具类java.util.Arrays 1.由于数组本身没有什么方法可以供我们调用,但在API中提供了一个工具类Arrays供我们使用,可以对数组进行一些基本操作 2.Arrays类中的方法都是static修饰的,可以直接使用 类名进行调用,比如Arrays.toString() 3.常用功能:1.给数组赋值:fill() 2.对数组升序排序:sort() 3.比较数组元素是否相等:equal() 4.查找数组元素:binarySearch() 4.导入Arrays类后选中它然后 ctrl+左键 就可以看其源码,然后找到并点击左下角边界那里的Structure可以查看这个类有多少方法 */ public class Demo05 { public static void main(String[] args) { int[] a={2,8,11,7,8,5,1}; System.out.println(Arrays.toString(a));//打印数组元素Arrays.toString(); Arrays.sort(a);//对数组进行升序排序(从小到大) System.out.println(Arrays.toString(a));//会输出排序后的a数组 //fill()两种使用方法,一种就是(数组名,数组元素值),另一种是(数组名,区域开始(包括该下标),区域结束(不包括该下标),区域内插入的数组元素值) int[] b=new int[5]; Arrays.fill(b,6); System.out.println(Arrays.toString(b)); int[] c=new int[5]; Arrays.fill(c,0,3,8);//相当于c[0]=8;c[1]=8;c[2]=8; Arrays.fill(c,3,5,7); System.out.println(Arrays.toString(c)); } }
7.稀疏数组
一.稀疏数组:一种二维数组
二.稀疏数组定义范围:array有效数字个数+1
三.稀疏数组介绍:
1.当一个数组中大部分元素都为0,或者为同一值的数组的时候,可以使用稀疏数组来保存该数组 2.稀疏数组的处理方式:
1.记录数组有几行几列,有多少个和0(或者最多的那个值)不同的值
2.把具有不同值的元素的行列及值记录在衣柜小规模数组中,从而缩小程序的规模
3.具体做法: 首先会统计原数组值的个数,因为 稀疏数组行数=有效值个数+1,而列数固定=3,即array有效值个数+1 第一行记录原数组几行几列,有几个值,也就是array0=行数-1;array0=列数-1;array0=值的个数 第二行开始记录第一个值的行数,列数,值,也就是array1=行数-1;array1=列数-1;array1=值 第三行记录第二个...
3.下图就是一个例子,原来的数组有6行7列8个有效数字,对应稀疏数组的第一行,稀疏数组一共8+1行;第一个有效数字22,在原数组的第1行第4列,对应稀疏数组第二行
package array; //稀疏数组:一种二维数组 /* 1.当一个数组中大部分元素都为0,或者为同一值的数组的时候,可以使用稀疏数组来保存该数组 2.稀疏数组的处理方式: 1.记录数组有几行几列,有多少个和0(或者最多的那个值)不同的值 2.把具有不同值的元素的行列及值记录在衣柜小规模数组中,从而缩小程序的规模 3.具体做法: 首先会统计原数组值的个数,因为 稀疏数组行数=有效值个数+1,而列数固定=3,即array[有效值个数+1][3] 第一行记录原数组几行几列,有几个值,也就是array[0][0]=行数-1;array[0][1]=列数-1;array[0][2]=值的个数 第二行开始记录第一个值的行数,列数,值,也就是array[1][0]=行数-1;array[1][1]=列数-1;array[1][2]=值 第三行记录第二个... 3.下图就是一个例子,原来的数组有6行7列8个有效数字,对应稀疏数组的第一行,稀疏数组一共8+1行;第一个有效数字22,在原数组的第1行第4列,对应稀疏数组第二行 */ public class Demo07 { public static void main(String[] args) { //原数组:创建一个11x11的棋盘,要求黑棋用1表示,白棋用2表示,空白处用0表示,此时有一颗黑棋在第二行第三列,一颗白棋在第三行第四列 System.out.println("创建好的原数组为:"); int[][] array1=new int[11][11];//二维数组范围就等于棋盘大小范围 array1[1][2]=1;//数组下标从0开始,所以对应的行列数要减1 array1[2][3]=2; for (int[] a1:array1) {//首先把二维数组的元素都赋值给一个以为数组a1 for (int a2:a1) {//其次又把一维数组a1所有元素赋值给int类型变量a2,这样就可以进行输出 System.out.print(a2+"\t"); } System.out.println();//每输出完一行换行 } System.out.println("=================================================================================="); //稀疏数组 //统计有几个有效数字(非0的数字) int sum=0; for(int i=0;i<array1.length;i++){ for(int j=0;j<array1[i].length;j++){ if(array1[i][j]!=0){ sum++; } } } System.out.println("有"+sum+"个有效数字"); //对稀疏数组进行创建并对其第一行进行赋值 int[][] array2=new int[sum+1][3];//创建的稀疏数组 行数=有效数字个数+1(因为第一行用来统计原数组行列数和有效数字个数),列固定为3列 array2[0][0]=11;//新行数第一个元素代表原来的数组有几行 array2[0][1]=11;//新行数第一个元素代表原来的数组有几列 array2[0][2]=sum;//新行数第一个元素代表有效数字在原数组有几个 //对稀疏数组进行赋值 int count=0;//对有效数字进行统计,也是对行数进行统计和改变, for(int i=0;i<array1.length;i++){ for (int j=0;j<array1[i].length;j++){ if(array1[i][j]!=0){ count++;//每有一个有效数字,行数就会加一 array2[count][0]=i;//新行数第一个元素代表有效数字在原数组第几行(赋值为行数-1) array2[count][1]=j;//新行数第二个元素代表有效数字在原数组第几列(赋值为列数-1) array2[count][2]=array1[i][j];//新行数第三个元素代表这个有效数字是几 } } } System.out.println("稀疏数组为"); //遍历然后输出稀疏数组 for(int i=0;i<array2.length;i++){ for(int j=0;j<array2[i].length;j++){ System.out.print(array2[i][j]+"\t"); } System.out.println(); } System.out.println("=================================================================================="); //还原原数组 int[][] array3=new int[array2[0][0]][array2[0][1]]; //给原数组赋值 for(int i=1;i< array2.length;i++){//稀疏数组存储原数组的单个有效数据信息从第二行开始,所以直接i从1开始 array3[array2[i][0]][array2[i][1]]=array2[i][2];//稀疏数组每行第一到三个元素分别存储原数组 行,列,值的信息 } System.out.println("原数组为"); for (int i=0;i<array3.length;i++){ for(int j=0;j<array3[i].length;j++){ System.out.print(array3[i][j]+"\t"); } System.out.println(); } } }
8.对象数组
如何创建并使用对象数组
1.在类中先定义好属性以及对应的get()set()方法(get()set()虽然不一定会被调用,但应该养成习惯)
2.一定要在类中定义一个有参的构造器,参数就是我们需要的数组成员,只需要将参数赋值给这个类的属性即可,使用this足够(关系到数组初始化)
3.在main方法中先创建一个该类的对象数组,具体格式: 类名 数组名[]=new 类名[数组长度]; 例如:OopArray a[]=new OopArray[3];
4.在main方法中开始对创建好的数组进行初始化,具体格式如下:
数组名[0]=new 类名{数组成员1,数组成员2...}
例如:a[0]=new OopArray("lihua",12);
*这里数组初始化就是用到了类里面的无参构造器
5.如果想直接输出数组对象,更直观查看数组的输出结果,就一定要重写对应的这个类里面的toString()方法,记得他有返回值,类型为String 例如:
@Override
public String toString(){//重写toString方法方便直接输出对象
return "{"+"name="+name+"\tage="+age+"}"; }
package array;
public class OopArray {
private String name;
private int age;
public static void main(String[] args) {
OopArray a[]=new OopArray[3];
a[0]=new OopArray("lihua",12);
a[1]=new OopArray("xiaohong",15);
a[2]=new OopArray("hong",14);
for (int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
//无参构造器
public OopArray(){
}
//有参构造器,方便初始化为数组格式
public OopArray(String name,int age){
this.name=name;
this.age=age;
}
//获取name属性,因为得获取到,所以是有返回值的,不然无法获取
public String getName(){
return this.name;
}
//设置name属性,只需要设置,所以不需要返回值
public void setName(String name){
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString(){//重写toString方法方便直接输出对象
return "{"+"name="+name+"\tage="+age+"}";
}
}