JavaSE| 数组
1、数组(array)
数组就是多个相同类型数据的组合,实现对这些数据的统一管理。 数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。数组属引用类型,数组型数据是对象(object),
每个元素相当于该对象的成员变量。相同数据类型的一组元素,数据,按照一定的顺序排列的集合。
把有限个相同类型的变量,使用统一的名称进行命名,以便统一管理它们,这个统一的名称我们称为“数组名”,每一个元素通过编号来区别,这个编号我们称为“索引index或下标”。组成数组的每一个数据我们称
为“元素element”,数组中元素的总个数,我们称为“数组的长度length”。
一个int类型的变量,存储一个整数值。
一、数组的声明
语法格式: 元素的数据类型[] 数组名;
数组名 = new 元素的数据类型[]{元素值1,元素值2...};
二、数组的初始化
1、目标: (1)确定数组的长度 (2)确定数组的元素值
2、动态初始化
语法格式:数组名 = new 元素的数据类型[长度];
先声明,再动态初始化如 String[] name;
name = new String[5];
声明+动态初始化如 int[] score = new int[5];
通过动态初始化的数组,元素有默认值,默认值也分为基本数据类型和引用数据类型。
基本数据类型:byte,short,int,long:0; float,double:0.0; char:\u0000,即字符编码为0的字符; boolean:false
引用数据类型:默认值统统都是null;例如String等类、接口、数组等类型
3、静态初始化:
语法格式:元素的数据类型[] 数组名 = {元素值1,元素值2...};
声明+静态初始化如: int[] day = {30,31,33};
先声明,后再静态初始化如:int[] day;
day = new int[]{ }
三 、手动赋值
数组名[下标] = 值;
说明:数组的下标的范围[0,数组的长度-1] ;如果下标越界,会报ArrayIndexOutOfBoundsException
数组的元素:数组名[下标],数组元素下标从0开始,长度为n的数组合法下标取值范围为0-->n-1;
数组的长度:数组名.length
定义并运用运算符new为之分配空间后,才可以引用数组中的每个元素。 数组一旦初始化,其长度是不可变的。
四、数组的遍历
for(int i=0; i<数组名.length; i++){
//数组名[i]代表一个元素
}
增强for循环
for(int num : arr){
System.out.print(num);
}
数组的遍历/赋值、最高分和最低分、数组的反转
class ShuZu{ public static void main(String[] args){ java.util.Scanner input = new java.util.Scanner(System.in); //输入小组人数 System.out.print("请输入小组人数:"); int count = input.nextInt(); //声明和初始化name和score数组 String[] name; //先声明 name = new String [count]; //动态初始化 int[] score = new int[count]; //声明+动态初始化 //遍历数组赋值 for (int i = 0; i < name.length; i++){ System.out.print("第" + (i+1) + "个同学的名字:"); name[i] = input.next(); System.out.print("第" + (i+1) + "个同学的成绩:"); score[i] = input.nextInt(); } //遍历数组 System.out.println("学生姓名和成绩如下:"); for (int i = 0;i < name.length;i++ ){ System.out.print(name[i] + ":"); System.out.print(score[i] + "分" + "\n"); } //对数组score进行遍历找出最高分和最低分 int max = score[0]; int min = score[0]; int indexMax = 0;// int indexMin = 0; int sum = 0; for(int i = 0; i < score.length; i++ ){ //也可以i < count; sum += score[i]; if(max < score[i]){ max = score[i]; indexMax = i; }if(min > score[i] ){ min = score[i]; indexMin = i; } }System.out.println("第"+ (indexMax+1) + "个同学" + name[indexMax] + "的成绩是最高的为:" + max); System.out.println("第"+ (indexMin+1) + "个同学" + name[indexMin] + "的成绩是最高的为:" + min); System.out.println("总分为:" + sum + "平均分是:" + sum/count); //数组的反转方法一(首尾对应位置交换,借助第三个变量) 下标i和下标score.length-1-i for(int i = 0;i <= score.length/2; i++){ int temp = score[i]; score[i] = score[score.length-1-i]; //[1,2,3,4,5,6] 1(0)和6(5);2(1)和5(4)... score[score.length-1-i] = temp; } for(int i = 0; i< score.length;i++){ System.out.print(score[i] + "\t"); } //数组的反转,方法二:借助一个空(新)数组 int[] temp = new int[count]; for(int i = 0;i < score.length;i++){ temp[i]=score[score.length-1-i]; } score = temp; //废弃旧数组,指向新数组 for(int i = 0;i < score.length;i++ ){ System.out.print(score[i] + "\t"); } } }
由基本数据类型创建的数组它的默认值:
public class TestArray0 { public static void main(String[] args){ //对于基于基本数据类型的变量创建的数组:byte short int long float double char boolean //1.对于byte short int long而已:创建数组以后,默认值为0 int[] scores = new int[4]; scores[0] = 89; scores[3] = 90; for(int i = 0;i < scores.length;i++){ System.out.println(scores[i]); } //2.对于float double而言;默认值是0.0 float[] f = new float[3]; f[0] = 1.2F; for(int i = 0; i < f.length;i++){ System.out.println(f[i]); } System.out.println(); //3.对于char而言,默认是空格 char[] c = new char[3]; for(int i = 0; i < c.length;i++){ System.out.println(c[i]); } System.out.println(); //4.对于boolean而言,默认是false boolean[] b = new boolean[3]; for(int i = 0; i < b.length;i++){ System.out.println(b[i]); } System.out.println(); //5.对于引用类型的变量构成的数组而言:默认初始化值为null。以String为例 String[] strs = new String[4]; strs[0] = "AA"; strs[1] = "BB"; //strs[2] = "CC"; 默认为null strs[3] = "DD"; //遍历数组的元素 for (int i = 0;i < strs.length;i++){ System.out.println(strs[i]); } //自定义的类 System.out.println(); Person[] pers = new Person[3]; for(int i = 0; i < pers.length;i++){ System.out.println(pers[i]); } } } class Person{ }
2、数组在内存中的结构
整个内存里边的基本结构就分这4部分:
new出来数组、对象;
方法区:类名、包名、方法的定义等;常量池、字符串常量池等,想用哪个从池子里边拿
静态区:静态的变量,用static修饰的变量等。
以数组为例,看它如何使用内存结构的:
java虚拟机进行解释运行对它进行初始化,栈先进后出,scores变量先存放在栈里边,每个内存里边都对应一个地址;new出来的放在堆里边。通过地址进行对应。
//数组一旦初始化,其长度是不可变的 public class TestAarry1 { public static void main(String[] args){ int[] i = new int[]{12,13,14}; int[] j = new int[10]; for(int k = 0;k < i.length;k++){ j[k] = i[k]; } j[3] = 15; j[4] = 16; for(int k = 0; k < j.length;k++){ System.out.println(j[k]); } } }
3、二维数组
数组的分类:
一维数组、二维数组、三维数组...多维数组:从二维开始都算多维数组,一般到二维就差不多了。
二维数组又称为矩阵。
先把一行看成一个整体的话,二维数组就是一个“特殊一维数组”; 二维数组的行数,就是“特殊一维数组”的长度,二维数组名.length;
一行同时又是一个一维数组,一行的列数,行.length; 行:就是“特殊一维数组”的一个元素,二维数组名[下标]
二维数组的表示方式
行:二维数组名[行下标] 行下标的范围[0, 总行数-1]
元素:二维数组名[行下标][列下标] 列下标的范围[0, 该行的总元素的个数-1]
行数:二维数组名.length
每一行的列数:二维数组名[行下标].length
二维数组的声明
元素的数据类型[][] 二维数组名;
例如:要存储每一组的学员的成绩,构成全班的成绩数组。
二维数组的初始化
1、静态初始化
二维数组名 = new 元素的数据类型[][]{{第一行的元素列表},{第二行的元素列表}....};
声明 + 静态初始化:元素的数据类型[][] 二维数组名 = {{第一行的元素列表},{第二行的元素列表}....};
int[][] scores2; //1. 先声明
scores2 = new int[][]{{1,2,3},{3,4,5},{6}}; //2.静态初始化
int[][] scores2 = {{1,2,3}, {3,4,5}, {6}}; //声明+静态初始化。
2、动态初始化
一维数组的动态初始化: 一维数组名 = new 元素的数据类型[长度];
二维数组的动态初始化:
1、每一行的列数是相同的,规则的矩阵
二维数组名 = new 元素的数据类型[行数][列数];
2、每一行的列数是不相同的,不规则的矩阵
(1)第一步先确定总行数
二维数组名 = new 元素的数据类型[行数][];
(2)依次确定每一行的列数
行 = new 元素的数据类型[列数];
for(int i = 0; i < arr.length; i++){ //确定每行的列数; --->> 为元素赋值 --->> 遍历显示 --->>换行 arr[i] = new int[i + 1]; } String[][] names; //1.二维数组的声明 //names = new String[6][5];//动态初始化的方式一 names = new String[6][0]; //动态初始化的方式二,先确定行数;再确定列数。 names[0] = new String[5]; names[1] = new String[3]; names[2] = new String[7]; names[3] = new String[9]; names[4] = new String[2]; names[5] = new String[4];
二维数组为元素赋值
二维数组名 [行下标][列下标] = 值;
二维数组的遍历
for(int i=0; i<行数; i++){
for(int j=0; j<每一行的列数; j++){
元素:二维数组名[行下标][列下标],即二维数组名[i][j]
}
}
package com.du.bai.www; public class TestArry2 { public static void main(String[] args){ int[] scores1 = new int[10]; int[][] scores2; String[][] names; //1.二维数组的初始化 scores2 = new int[][]{{1,2,3},{3,4,5},{6}}; //静态初始化 names = new String[6][5];//动态初始化的方式一 names = new String[6][0]; //动态初始化的方式二 names[0] = new String[5]; names[1] = new String[3]; names[2] = new String[7]; names[3] = new String[9]; names[4] = new String[2]; names[5] = new String[4]; //错误的初始化方式 //names = new String[][]; //names = new String[][5]; //2.如何来引用具体的某一个元素 int[][] i = new int[3][2]; //int[] i[] = new int[3][2]; i[1][0] = 90; i[2][1] = 89; //3.数组的长度 //二维数组的长度;length属性 System.out.println(i.length); //3 //二维数组中元素的长度 System.out.println(i[0].length); //2 System.out.println(names.length); //6 System.out.println(names[4].length); //8 System.out.println(); //4.如何遍历二维数组 for(int m = 0; m < scores2.length;m++){ //控制行数 for(int n = 0;n < scores2[m].length;n++){ System.out.print(scores2[m][n] + " "); } System.out.println(); } } }
异常:下标越界、空指针
public class TestException { public static void main(String[] args){ //1.数组下标越界异常:java.lang.ArrayIndexOutOfBoundsException int[] i = new int[10]; //i[0] = 90; //i[10] = 99; // for (int m = 0;m <= i.length;m++){ // System.out.println(i[m]); // } //2.空指针的异常:NullPointerException //第一种: // boolean[] b = new boolean[3]; // b = null; // System.out.println(b[0]); //第二种: // String[] str = new String[4]; // str[3] = new String("AA"); //str[3] = "AA"; // System.out.println(str[3].toString()); //第三种: int[][] j = new int[3][]; j[2][0] = 12; } }
public class TestGetSum { public static void main(String[] args){ int[][] m = new int[][]{{3,8,2},{2,7},{9,0,1,6}}; int sum = 0; for (int i = 0;i < m.length;i++){ for(int j = 0;j < m[i].length;j++){ System.out.print(m[i][j] + "\t"); sum += m[i][j]; } System.out.println(); } System.out.println("总和为:" + sum); } }
杨辉三角
public class TestYangHui { public static void main(String[] args){ int[][] yangHui = new int[10][]; //1.初始化二维数组 for(int i = 0;i < yangHui.length;i++){ yangHui[i] = new int[i + 1]; } //2.显示的为二维数组的每个元素赋值 for(int i = 0;i < yangHui.length;i++){ for(int j = 0;j < yangHui[i].length;j++){ yangHui[i][0] = yangHui[i][i] = 1; if (i > 1 && j > 0 && j < i){ 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] + "\t"); } System.out.println(); } } }
4、API| 数组工具类
API:应用程序编程接口,俗称“帮助文档” java.util.Arrays:数组工具类 此类包含用来操作数组(比如排序和搜索)的各种方法。 (1)int binarySearch(int[] a, int key) a - 要搜索的数组 key - 要搜索的值 结果:如果它(key)包含在数组(a)中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 插入点:被定义为将键(key)插入数组(a)的那一点 二分查找的前提:数组必须是有序的 (2)void sort(int[] a) :对指定的 int 型数组按数字升序进行排序。 (3)int[] copyOf(int[] original, int newLength) 如:Arrays.copyOf(arr, arr.length * 2); 扩容为原来的2倍。 复制指定的数组,截取或用 0 填充(如有必要),以使副本具有指定的长度。 Arrays..copyOf(arr, total);返回数组实际存储的元素; original - 要复制的数组,源数组 newLength - 要返回的副本的长度 结果:原数组的副本,截取或用 0 填充以获得指定的长度 (4)int[] copyOfRange(int[] original, int from, int to) original - 将要从其复制一个范围的数组,源数组 from - 要复制的范围的初始索引(包括) to - 要复制的范围的最后索引(不包括)。(此索引可以位于数组范围之外)。 结果:original数组的[from,to) (5) void fill(int[] a, int val) 将指定的 int 值分配给指定 int 型数组的每个元素。 a - 要填充的数组 val - 要存储在数组所有元素中的值 (6)String toString(int[] a) 返回指定数组内容的字符串表示形式。字符串表示形式由数组的元素列表组成,括在方括号("[]")中。 相邻元素用字符 ", "(逗号加空格)分隔。 a - 返回其字符串表示形式的数组 结果:a 的字符串表示形式,是一个字符串 .... class TestApi{ public static void main(String[] args){ //java.util.Scanner //1.找下标 int[] arr = {8,2,0,4,5,1,6,9,3}; int find = 5; int index = java.util.Arrays.binarySearch(arr,find); //因为这个工具的binarySearch方法会返回一个结果,所以我要用一个变量接收这个结果 System.out.println("index=" + index); //2.排序,从小到大 java.util.Arrays.sort(arr); for(int i = 0;i < arr.length; i++){ System.out.print(arr[i] + "\t"); } //3.复制一个和原来长度一模一样的数组,两倍长就是arr.length * 2 //int[] xin = java.util.Arrays.copyOf(arr, arr.length); //复制数组前3个; //int[] xin = java.util.Arrays.copyOf(arr, 3); //要复制arr数组,但是我想要从arr[2]复制到arr[5], //int[] xin = java.util.Arrays.copyOfRange(arr,3,5+1); //要复制arr数组,但是我想要从arr[2]开始到最后,并且新数组的长度是10 //假设原数组够长,新数组的长度要10,从[2]~[11],但是11不包含,所以写12 //int[] xin = java.util.Arrays.copyOfRange(arr, 2, 12); //4.填充 int[] arr1 = new int[10];//用3填充数组arr //java.util.Arrays.fill(arr1, 3); java.util.Arrays.fill(arr1, (int)(Math.random()*100)); for(int num : arr1){ System.out.print(num + "\t"); } String str = java.util.Arrays.toString(arr); System.out.println(str); } }
数组的增加
创建添加信息对象;然后将对象作为参数传给数组