1.一维数组内存结构分析
2.一维数组概述
package com.yl.pdfdemo.day02;
import java.util.Arrays;
import java.util.Scanner;
/**
* @Author wfj
* @Date 2021/1/21
* @Description 数组的使用
* @Version 1.0
*/
public class ArrayTest1 {
public static void main(String[] args) {
/**
* 一:数组概述
*1.数组的理解:数组(Array),是多个相同类型的数据按照一定顺序排列的集合,并且使用一个名字命名
* 并通过编号的方式对这些数据进行统一管理
*
* 2.数组的相关概念
* 》数组名
* 》元素
* 》角标 、下标 、索引、
* 》数组的长度:元素的个数
*
* 3.数组的特点
* 1)数组是有序排列的
* 2)数组属于引用数据类型变量,数组中的元素可以为任意的数据类型
* 3)创建数组对象,会在内存中,开辟出一块连续的空间,而数组名引用的是这块连续空间的首地址
* 4)数组的长度一旦确定下来,就不能改变
*
* 4.数组的分类
* 1)按照维度来划分:一维数组,二维数组。。。
* 2)按照数组元素的类型,基本数据类型元素的数组,引用数据类型元素的数组
*
* 5.一维数组的使用
* 1)一维数组的声明和初始化
* 2)如何调用数组的指定位置的元素
* 3)如何获取数组的长度
* 4)如何遍历数组
* 5)数组元素的默认初始化值
* 6)数组的内存解析
*
*
*
*/
//1.一维数组的声明和初始化
int[] ids; //声明
//静态初始化:数组的初始化和赋值同时进行
ids = new int[]{1001,1002,1003,1004,10005};
//也可以这样声明和赋值,注意,这样写,不能分开声明和赋值这两个步骤
int ages[] = {18,28,38}; //类型推断
//动态初始化:数组的初始化和赋值分开进行
String[] names = new String[5];
//错误的写法
// int[] arr1 = new int[];
// int[5] arr2 = new int[5];
// int[] arr3 = new int[3]{1,2,3};
//注意:数组一旦初始化完成,其长度就确定了
//2.如何调用数组指定位置的元素,通过角标的调用方式
//数组的角标(索引)从0开始一直到数组长度-1
names[0] = "小舞";
names[1] = "唐三";
names[2] = "宁荣荣";
names[3] = "马红俊";
names[4] = "比比东";
//3.如何获取数组的长度
//通过数组的属性length
System.out.println(names.length);//5
//4.如何遍历数组
for (int i = 0; i < names.length; i ++) {
System.out.println(names[i]);
}
//5.数组元素的默认初始化值
int[] arr1 = new int[5];
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);//0
}
/**
* 数组的默认值
* 数组元素是整形时:0
* 数组元素为浮点型时:0.0
* 数组元素为char时:0 或'\u0000'
* 数组元素为boolean型时:false
* 数组元素为引用数据时:null
*/
//练习1
int[] arr = new int[] {8,2,1,0,3};
int[] index = new int[] {2,0,3,2,4,0,1,3,2,3,3};
String tel = "";
for (int i = 0;i < index.length; i++) {
tel += arr[index[i]];
}
System.out.println(tel);
//练习2
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生个数:");
int num = scanner.nextInt();
System.out.println("请输入这"+num+"学生的成绩:");
int[] scores = new int[num];
for (int i = 0; i < scores.length; i++) {
scores[i] = scanner.nextInt();
}
int max = 0;
//求最大值
for (int i = 0; i < scores.length; i++) {
if (scores[i] > max) {
max = scores[i];
}
}
char c;
for (int i = 0; i < scores.length; i++) {
if (max - scores[i] <= 10) {
c = 'A';
} else if (max - scores[i] <= 20){
c = 'B';
} else if (max - scores[i] <= 30) {
c = 'C';
} else {
c = 'D';
}
System.out.println("学生"+i+"的成绩是"+scores[i]+",级别是"+c);
}
//练习3
/**
* 定义一个长度为10的数组,元素为随机的不可以重复的两位数[10,99]
* 求这个数组的最大值,最小值,平均值和总和
*/
int[] arrs = new int[10];
for (int i = 0; i< arrs.length; i ++) {
arrs[i] = (int)(Math.random() * 90 + 10);
}
// 打印这10个随机数
Arrays.stream(arrs).forEach(item -> {
System.out.println(item);
});
int maxnum = 0;
int minnum = arrs[0];
int sum = 0;
int avg = 0;
for (int i = 0; i < arrs.length; i++) {
if (arrs[i] > maxnum) {
maxnum = arrs[i];
}
}
System.out.println("最大值为:" + maxnum);
for (int i = 1; i < arrs.length; i++) {
if (arrs[i] < minnum) {
minnum = arrs[i];
}
}
System.out.println("最小值为:" + minnum);
for (int i = 0; i < arrs.length; i++) {
sum += arrs[i];
}
System.out.println("总和为:"+sum);
System.out.println("平均值为:"+sum/arrs.length);
/**
* 关于数组的复制问题
*/
int[] a,b;
a = new int[]{1,2,5,8,19};
Arrays.stream(a).forEach(item -> {
System.out.println(item);
});
//注意:这样并不能说是复制数组,事实上,a的地址指向内存的一块空间,
// b=a其实就是将a的地址赋值给b,所有两者是指向同一块内存空间的
b = a;
for (int i = 0; i < b.length; i++) {
if (i % 2 == 0) {
b[i] = i;
}
}
Arrays.stream(b).forEach(item -> {
System.out.print(item + " ");//02284
});
Arrays.stream(a).forEach(item -> {
System.out.print(item + " ");//02284
});
/**
* 数组的赋值,反转,查找
*/
//1.复制,strs和strs1这时候指向两个不同的内存区域
String[] strs = new String[] {"aa","bb","cc","dd","ee"};
String[] strs1 = new String[strs.length];
for (int i = 0; i < strs.length; i++) {
strs1[i] = strs[i];
}
//2.反转(方式1)
// for (int i = 0; i < strs.length/2; i++) {
// String temp = strs[i];
// strs[i] = strs[strs.length - i -1];
// strs[strs.length - i - 1] = temp;
// }
//2.反转(方式2)
for (int i = 0,j = strs.length-1;i < j; i++,j--) {
String temp = strs[i];
strs[i] = strs[j];
strs[j] = temp;
}
Arrays.stream(strs).forEach(item -> {
System.out.print(item + " ");
});
//3.查找(搜索)
String s = "cc";
for (int i = 0; i < strs.length; i++) {
if (s.equals(strs[i])) {
System.out.println("找到了目标:"+ s +"其索引为:"+i);
break;
}
}
}
}
3.二维数组内存结构分析
4.二维数组概述
package com.yl.pdfdemo.day02;
/**
* @Author wfj
* @Date 2021/1/21
* @Description 二维数组
* @Version 1.0
*/
public class ArrayTest2 {
public static void main(String[] args) {
/**
* 理解:
* 对于二维数组的理解,我们可以看成是一维数组array1又作为另外一个一维数组array2的元素的存在
* 其实,从数组底层的运行机制来看,其实没有多维数组
*
* 1.二维数组的使用
* 1)二维数组的声明和初始化
* 2)如何调用数组的指定位置的元素
* 3)如何获取数组的长度
* 4)如何遍历数组
* 5)数组元素的默认初始化值
* 6)数组的内存解析
*/
//1.二维数组的声明和初始化
int[] arr = new int[]{1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7}};
//或者
int[] arr11[] = new int[][]{{1,2,3},{4,5},{6,7,8}};
int[] arr12[] = {{1,2,3},{4,5},{6,7,8}};
//动态初始化1,相当于一个表格,3行2列
String[][] arr2 = new String[3][2];
//动态初始化2
String[] arr3[] = new String[3][];//相当于建了3行,但是列并没有创建,所以直接引用行不会报错,但是引用列则会报错
//错误的写法
//String[][] arr4 = new String[][4];
//String[4][3] arr5 = new String[][];
// int[][] arr6 = new int[4][3]{{1,2,3},{2,3}};
//2.如何调用数组的的指定位置的元素
System.out.println(arr1[0][1]);//2
System.out.println(arr2[1][1]);//null
//System.out.println(arr3[1][0]);//报空指针异常
arr3[1] = new String[3];//这里相当于第2行创建3列
System.out.println(arr3[1][0]);//null
System.out.println(arr3[0]);//null
//3、读取数组的长度
System.out.println(arr1.length);//3
System.out.println(arr1[0].length);//3
System.out.println(arr1[1].length);//2
System.out.println(arr1[2].length);//2
//4、如何遍历二维数组
for (int i = 0; i < arr1.length; i++) { //遍历行数
for (int j = 0; j < arr1[i].length; j++) { //列内容
System.out.print(arr1[i][j]);
}
System.out.println();
}
//5.二维数组元素的默认初始化值
/**
* 初始化1:int[][] arr = new int[3][5]
* 外层元素的初始化值:地址值
* 内层元素的初始化值:与一维数组的一样
* 初始化2:int[][] arr = new int[6][]
* 外层元素的初始化值为null
* 内层元素的初始化值:不能调用,否则报错
*/
//int
int[][] doubleArr = new int[4][3];
System.out.println(doubleArr[0]);//[I@30f39991(地址值)
System.out.println(doubleArr[0][0]);//0
//float
float[][] doubleArr1 = new float[4][3];
System.out.println(doubleArr1[0]);//[F@452b3a41(地址值)
System.out.println(doubleArr1[0][0]);//0.0
//String
String[][] doubleArr2 = new String[4][3];
System.out.println(doubleArr2[0]);//[Ljava.lang.String;@4a574795(地址值)
System.out.println(doubleArr2[0][0]);//null
double[][] doubleArr3 = new double[3][];
System.out.println(doubleArr3[0]);//null
//System.out.println(doubleArr3[0][0]);//报空指针错误
//练习1,求二维数组所有值的和
int[][] doublearr = new int[][] {{3,5,8},{12,9},{7,10,3,6}};
int sum = 0;
for (int i = 0; i < doublearr.length; i++) {
for (int j = 0; j < doublearr[i].length; j++) {
sum += doublearr[i][j];
}
}
System.out.println("总和为:"+sum);//63
//二维数组的一些小坑
/**
* 提示:
* 一维数组:int[]x 或者int x[]
* 二维数组:int[][] y 或者int [] y [] 或者int y [][]\
* 声明:int[] x,y[],在给下x,y变量赋值之后,以下选项允许编译通过的是
* 注意:以上声明拆分为int[]x(一维数组) 和int[][]y(二维数组)
* 1.x[0] = y; 不可以
* 2.y[0] = x; 可以
* 3.y[0][0] = x; 不可以
* 4.x[0][0] = y; 不可以
* 5.y[0][0] = x[0] 可以
* x= y; 不可以
*/
//练习,杨辉三角(打印10行)
/**
* 1
* 1 1
* 1 2 1
* 1 3 3 1
* 1 4 6 4 1
* 1 5 10 10 5 1
* 省略。。
*
* 以上有这么一个规律
* 1.每一行的第一个和最后一个元素都是1
* 2.从第三行开始,假设我们定义了一个二维数组,int[][]x
* 我们可以得出公式: x[i][j] = x[i-1][j-1]+x[i-1][j] =>[i]等于行 而[j]等于列
* 第三行,2 = x[2][1] = x[1][0] + x[1][1] = 1+1
*
* 第四行的,
* 3 = x[3][1] = x[2][o] + x[2][1] = 1+2
* 3 = x[3][2] = x[2][1] + x[2][2] = 2+1
*
*/
//初始化二维数组
int[][] yang = new int[10][];
//给数组的元素赋值
for (int i = 0; i < yang.length; i++) {
yang[i] = new int[i + 1];
//给每一行的首末元素赋值为1
yang[i][0] = yang[i][i] = 1;
//非首末元素赋值,第三行时,执行yang[i][j] = yang[i-1][j-1] + yang[i-1][j];
if (i > 1) {
for (int j = 1; j < yang[i].length - 1; j++) {
yang[i][j] = yang[i-1][j-1] + yang[i-1][j];
}
}
}
//遍历二维数组
for (int i = 0 ; i < yang.length; i++) {
for (int j = 0; j < yang[i].length; j++) {
System.out.print(yang[i][j] + " ");
}
System.out.println();
}
}
}