个人向学习记录--数组
数组的概述
数组Array :是相同类型的数据,按一定顺序排列的集合,并使用一个名字来命名,并通过编号的方式来对数据进行统一管理
常见概念:
数组名
元素
下标(索引、角标)
长度
数组的特点:
- 数组是序排列的
- 数组属于引用数据类型。但是数组的元素,既可以是基本数据类型(int 、double),也可以是引用数据类型(String)
- 创建数组对象会在内存中开辟一整块连续的空间
- 数组的长度一旦确定,就不能修改。
一维数组
声明和初始化
public class Exercise{
public static void main(String[] args) {
//普通的声明
int num; //声明
num=10;
int id=1001; //声明+初始化
//静态初始化,数组的初始化和数值的赋值同时进行
int[] ids= new int[]{1,2,3,4};
//动态初始化,数组的初始化和数值的赋值分开进行
String[] names= new String[4];
}
};
一旦初始化完成,数组长度就确定了
调用数组指定位置的元素
通过索引方式调用
String[] names= new String[5];
//注意:角标从0开始,到n-1结束
names[0]="小莫";
names[1]="小能";
names[2]="小风";
names[3]="小陈";
names[4]="小塔";
如何获取数组的长度
属性:length
String[] names= new String[5];
//注意:角标从0开始,到n-1结束
names[0]="小莫";
names[1]="小能";
names[2]="小风";
names[3]="小陈";
names[4]="小塔";
System.out.println(names.length);
输出: 5
如何遍历数组元素
String[] names= new String[5];
//注意:角标从0开始,到n-1结束
names[0]="小莫";
names[1]="小能";
names[2]="小风";
names[3]="小陈";
names[4]="小塔";
//for循环
for(int i=0;i<names.length;i++){
System.out.print(names[i]+" ");
}
输出:小莫 小能 小风 小陈 小塔
数组元素默认初始化的值
元素为整型(byte、short、int、long)的话,默认值都是0
元素为浮点型(double、float)的话,默认值为0.0
元素为char型,默认值为空字符
元素为boolean型,默认值为false (0)
元素为String型,默认值为NULL,没有赋值的意思
int[] arr=new int[4]; //元素为int整型
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
输出:0 0 0 0
char[] arr=new char[4]; //char类型
for(int i=0;i<arr.length;i++){
System.out.println("111"+arr[i]+"12");
}
//char类型里面的0
if(arr[1]==0){
System.out.println("你好");
}
结果:
111 12
111 12
111 12
111 12
你好
String[] arr=new String[4];
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
if(arr[0]==null){
System.out.println("对了");
}
结果:
null
null
null
null
对了
数组的内存解析
内存结构的简单说明:
解析:栈里的arr首地址对应堆里的首地址,然后将堆里开辟的空间一一填上所赋予的数值,比如arr1[1],本来是null,后来成了刘德华。
之后arr[1]被赋予了新的首地址,进入了新的堆空间,所以之前的那个"刘德华堆"就没有引用指向了,到时候就会被回收掉
练习:
public class Exercise{
public static void main(String[] args) {
//使用scanner读取学生个数
Scanner scan = new Scanner(System.in);
System.out.println("请输入学生人数");
int number =scan.nextInt();
//创建数组
int[] scores=new int[number];
//给数组中元素赋值
System.out.println("请输入"+number+"个学生的成绩");
for(int i=0;i<scores.length;i++){ //注意这里不能写<=,因为数组是从0开始的,写<=会卡循环
scores[i]=scan.nextInt();
}
//获取数组中元素的最高分
int max=0;
for(int i=0;i<scores.length;i++){
if(max<scores[i]){
max=scores[i];
}
}
//根据每个学生成绩与最高分的差值,得到学生的等第,并输出成绩与等第
String level;
for(int i=0;i<number;i++){
if(max-scores[i]<=10){
level="A";
}
else if (max-scores[i]<=20){
level="B";
}
else if (max-scores[i]<=30){
level="C";
}
else {
level="D";
}
System.out.println(i+"号学生"+" 成绩"+scores[i]+" 等第"+level);
}
}
};
结果:
请输入学生人数
4
请输入4个学生的成绩
10
30
40
100
0号学生 成绩10 等第D
1号学生 成绩30 等第D
2号学生 成绩40 等第D
3号学生 成绩100 等第A
二维数组
理解:一个一维数组arr1作为另一个arr2数组中的元素而存在
声明和初始化
//静态初始化
int []arr =new int[]{1,2,3}; //一维
int[][] arr1 =new int[][]{ {1,2,3},{4,5,6},{8,9,0} }; //二维
//动态初始化
String[][] arr2 =new String[3][3]; //三个数组,每个数组里有三个元素
String[][] arr3 =new String[3][]; //三个数组,数组里面还没赋值,也可以
调用元素
//静态初始化
int[][] arr1=new int[][]{ {1,2,3},{4,5,6},{8,9,0} }; //二维
//动态初始化
String[][] arr2 =new String[3][3]; //三个数组,每个数组里有三个元素
String[][] arr3 =new String[3][]; //三个数组,数组里面还没赋值,也可以
System.out.println(arr1[0][1]); // 2 第一个数组中的第二个值
System.out.println(arr2[0][1]); // null,因为没赋值
结果:2 null
获取二维数组的长度
//静态初始化
int[][]arr1=new int[][]{ {1,2,3},{4,5},{6,7,8,9} }; //二维
//动态初始化
String[][] arr2 =new String[3][2]; //三个数组,每个数组里有三个元素
String[][] arr3 =new String[3][]; //三个数组,数组里面还没赋值,也可以
System.out.println(arr1.length); //3,指的是数组的长度
System.out.println(arr2.length); //3,指的是数组的长度
System.out.println(arr3.length); //3,指的是数组的长度
System.out.println(arr1[0].length); //3 是{123}的长度
System.out.println(arr1[1].length); //2 是{45}的长度
System.out.println(arr1[2].length); //4 是{6789}的长度
遍历二维数组
//静态初始化
int[][]arr1=new int[][]{ {1,2,3},{4,5},{6,7,8,9} }; //二维
for(int i=0;i<arr1.length;i++){ //遍历每一个数组
for(int j=0;j<arr1[i].length;j++){ //遍历第i个数组中的每一个元素
System.out.print(arr1[i][j]+" ");
}
System.out.println();
}
结果:
1 2 3
4 5
6 7 8 9
二维数组的默认初始化值
二维数组分为外层数组的元素和内层数组的元素
外层:arr[0]、 arr[1] 等
内层:arr[0][0]、arr[1][2]等
//动态初始化
String[][] arr2 =new String[3][2]; //三个数组,每个数组里有三个元素
String[][] arr3 =new String[3][]; //三个数组,数组里面还没赋值,也可以
System.out.println(arr2[0]); //地址值
System.out.println(arr2[0][0]); //null
System.out.println(arr2); //二维数组的地址值
System.out.println(arr3[0][1]); //报错。空指针异常
System.out.println(arr3[0]); //null ,因为此时内部元素还没有,为空
结果:
[Ljava.lang.String;@4554617c
null
[[Ljava.lang.String;@74a14482
Exception in thread "main" java.lang.NullPointerException
at Text.Exercise.main(Exercise.java:18)
针对于初始化方式一: 比如:int[][] arr = new int[4][3];
外层元素的初始化值为:地址值
内层元素的初始化值为:与一维数组初始化情况相同
针对于初始化方式二: 比如:int[][] arr = new int[4][];
外层元素的初始化值为:null
内层元素的初始化值为:不能调用,否则报错。
内存解析
插曲:当时写着写着,突然心血来潮修改了一下main方法,后来IDEA运行时报错找不到 main 方法,本来可以运行,但是突然无法运行,突然报下面的错误:
****中找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.application.Application
解决方法:
删除 import.com.sun.org.apache.xpath.internal.operations.String;这个包
练习
int[][] arr=new int[][]{{3,5,8},{12,9},{7,0,6,4}};
int sum=0;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
System.out.print(arr[i][j]+" ");
sum+=arr[i][j];
}
System.out.println();
}
System.out.println("sum="+sum);
结果:
3 5 8
12 9
7 0 6 4
sum=54
练习:杨辉三角
//声明数组
int[][] arr=new int[10][];
//给元素赋值
for(int i=0;i<arr.length;i++){
arr[i]=new int[i+1]; //十行,每行多一位
//给首末元素赋值
arr[i][0]=1;
arr[i][i]=1;
//给非首末元素赋值
if(i>1){
for(int j=1;j<arr[i].length-1;j++){ //除首末的元素
arr[i][j]=arr[i-1][j-1]+arr[i-1][j]; //杨辉三角算法
}
}
}
//遍历二维数组
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();
}
结果:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
数组常见算法
数组元素的赋值
杨辉三角 回形数
练习:定义一个int[] arr=new int[6]; 需要输出1~30之内的随机数,并且不能重复。
int[] arr=new int[6];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*30)+1;
for(int j=0;j<i;j++){
if(arr[i]==arr[j]){
i--;
break;
}
}
}
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
求值型数组中元素的最大值最小值平均数等
练习:
int[] arr=new int[10];
int sum=0;
int account=0;
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*90+10);
System.out.println(arr[i]);
sum+=arr[i];
account++;
}
System.out.println("总和="+sum);
System.out.println("平均数="+sum/account);
//最大值
int max=arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i]>max){
max=arr[i];
}
}
System.out.println("max="+max);
//最小值
int min=arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i]<min){
min=arr[i];
}
}
System.out.println("min="+min);
结果:
55
87
36
72
15
45
96
25
26
84
总和=541
平均数=54
max=96
min=15
数组复制、反转、查找
将array1保存的数组的地址值赋给了array2,使得array1和array2共同指向堆空间中的同一个数组实体。