- 数组
- 数组的定义
- 静态初始化数组
- 静态初始化数组的格式:
- 静态初始化数组的基本原理
- 总结
- 数组的访问
- 总结
- 数组的几个注意事项
- 动态初始化数组
- 总结
- 动态初始化数组的元素默认值
- 总结
- 数组的遍历
- 数组遍历介绍
- 案例
- 数组元素求和
- 数组求最值
- 猜数字游戏
- 随机排名经典
- 数组的内存图
- Java内存分配
- 数组内存图
- 两个变量指向同一个数组
- 数组使用的常见问题
- 问题1:
- 问题2:
- 二维数组
- 数组的(面试题)
- 数组复制
- 数组反转
- 数组排序(面试题冒泡排序)
- 总结
- 数组查找(面试题二分查找)
- 线性查找
- 二分查找
数组 数组的定义 作者: gh-xiaohe
gh-xiaohe的博客
觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!
数组是什么
- 数组就是用来存储一批同种类型数据的内存区域(可以理解成容器)。
例子
结论:数组适合做一批同种类型数据的存储。
静态初始化数组- 定义数组的时候直接给数组赋值。
public class ArrayDemo1 {
public static void main(String[] args) {
// 目标:学会使用静态初始化的方式定义数组
// 数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,...}
// double[] scores = new double[]{99.5, 88.0, 75.5};
double[] scores = {99.5, 88.0, 75.5}; // 简化写法
System.out.println(scores + " ---> " + "输出的是数组的地址");
// int[] ages = new int[]{12, 24, 36};
int[] ages = {12, 24, 36};
System.out.println(ages + " ---> " + "输出的是数组的地址");
// String[] names = new String[]{"牛二", "全蛋儿", "老王"};
String[] names = {"牛二", "全蛋儿", "老王"};
System.out.println(names + " ---> " + "输出的是数组的地址");
System.out.println("names.length = " + names.length);
System.out.println("names[0] = " + names[0]);
System.out.println("names[1] = " + names[1]);
System.out.println("names[2] = " + names[2]);
}
}
静态初始化数组的基本原理
注意:数组变量名中存储的是数组在内存中的地址,数组是引用类型。
总结-
数组的静态初始化的写法和特点什么样的?
-
数组是属于什么类型,数组变量名中存储的是什么?
- 引用数据类型,存储的数组在内存中的地址信息。
数组的访问
数组的长度属性:length
问题:数组的最大索引可以怎么表示?
public class ArrayDemo2 {
public static void main(String[] args) {
// 目标:学会访问数组的元素
int[] ages = {12, 24, 36};
// 0 1 2
// 取值: 数组名称[索引]
System.out.println(ages[0]); // 12
System.out.println(ages[1]); // 24
System.out.println(ages[2]); // 36
// 赋值:数组名称[索引] = 数据;
ages[2] = 100;
System.out.println(ages[2]);// 100
// 访问数组的长度
System.out.println(ages.length); // 3
int[] arr = {};
System.out.println(arr.length - 1);// -1
}
}
总结
-
如何访问数组的元素?
-
如何访问数组的长度?
- 数组名称.length
-
数组的最大索引怎么获取?
-
“数据类型[] 数组名”也可以写成。 “数据类型 数组名[] ”
-
什么类型的数组存放什么类型的数据,否则报错。
-
数组一旦定义出来,程序执行的过程中,长度、类型就固定了。
public class ArrayAttentionDemo3 {
public static void main(String[] args) {
// 目标:理解数组的注意事项
// 1、数据类型[] 数组名称 也可以写成 数据类型 数组名称[]
int[] ages = {11, 23, 45};
// int ages1[] = {11, 23, 45};
// 2、什么类型的数组只能存放什么类型的元素
// String[] names = {"西门吹雪", "独孤求败", 23}; // 错误的
// 3、数组一旦定义出来之后,类型和长度就固定了
int[] ages2 = {11, 23, 45};
System.out.println(ages2[3]); // 报错! 长度固定是3了不能访问第4个元素!! 数组越界!!
}
}
动态初始化数组
-
定义数组的时候只确定元素的类型和数组的长度,之后再存入具体数据。
public class ArrayDemo4 { public static void main(String[] args) { // 目标:学会动态初始化数组的定义和使用。 double[] scores = new double[3]; // [0.0, 0.0, 0.0] // 0 1 2 // 赋值 scores[0] = 99.5; System.out.println(scores[0]); // 99.5 System.out.println(scores[2]); // 未赋值,默认为0.0 String[] names = new String[90]; names[0] = "迪丽热巴"; // 这里不能直接赋值,因为数组的类型是Object,所以需要转换 names[2] = "马尔扎哈"; System.out.println(names[0]); // 迪丽热巴 System.out.println(names[1]); // null System.out.println(names[2]); // 马尔扎哈 } }
-
动态初始化的写法是什么样的?
-
两种数组定义时的特点和场景有什么区别
- 当前已经知道存入的元素值,用静态初始化。
- 当前还不清楚要存入哪些数据,用动态初始化。
元素默认值规则
两种初始化的的使用场景总结、注意事项说明:
public class ArrayDemo5 {
public static void main(String[] args) {
// 目标:掌握动态初始化元素默认值的规则。
// 1、整型数组的元素默认值都是0
int[] arr = new int[10];
System.out.println(arr[0]); // 0
System.out.println(arr[9]); // 0
// 2、字符数组的元素默认值是多少呢? 0
char[] chars = new char[100];
System.out.println((int)chars[0]); // 0
System.out.println((int)chars[99]); // 0
// 3、浮点型数组的元素默认值是0.0
double[] scores = new double[90];
System.out.println(scores[0]); // 0.0
System.out.println(scores[89]); // 0.0
// 4、布尔类型的数组
boolean[] booleans = new boolean[100];
System.out.println(booleans[0]); // false
System.out.println(booleans[99]); // false
// 5、引用类型的数组
String[] names = new String[90];
System.out.println(names[0]); // null
System.out.println(names[89]); // null
// int[] arrs = new int[3]{30, 40, 50}; // 两种格式的写法是独立的,不可以混用。
int[] a = {1,2,3};
int[] b = {1,2,3};
System.out.println(a); // [I@1c9d8f0
System.out.println(b); // [I@1c9d8f0
}
}
总结
- 动态初始化数组后元素的默认值是什么样的?
- byte、short、int 、char、long类型数组元素的默认值都是0
- float、double类型数组元素的默认值都是0.0
- boolean类型数组元素的默认值是false、String类型数组元素的默认值是null
- 遍历:就是一个一个数据的访问。
- 为什么要遍历? 搜索、数据统计等等都需要用到遍历。
public class ArrayDemo {
public static void main(String[] args) {
// 目标:学会进行数组元素的遍历
int[] arr = {12, 24, 12, 48, 98};
// 0 1 2 3 4
// 原始遍历方式
// System.out.println(arr[0]);
// System.out.println(arr[1]);
// System.out.println(arr[2]);
// System.out.println(arr[3]);
// System.out.println(arr[4]);
// for (int i = 0; i < 5; i++) {
// System.out.println(arr[i]);
// }
// 终极数组遍历形式
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
案例
数组元素求和
需求:某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的总销售额。
public class Test1 {
public static void main(String[] args) {
// 需求:数组元素求和
// 1、把这些数据拿到程序中使用数组记住
int[] money = {16, 32, 8, 100, 78};
// 3、定义一个求和变量累加数组的元素值
int sum = 0;
// 2、遍历数组中的每个元素
for (int i = 0; i < money.length; i++) {
// 拿到每个元素值累加
sum += money[i];
}
// 4、输出求和变量即可
System.out.println("数组的元素和是:" + sum);
}
}
数组求最值
public class Test2 {
public static void main(String[] args) {
// 需求:数组元素求最值。
// 1、定义一个静态初始化的数组,存储一批颜值。
int[] faceScore = {15, 9000, 10000, 20000, 9500, -5};
// 0 1 2 3 4 5
// 2、定义一个变量用于存储最大值元素,建议使用第一个元素作为参照。
int max = faceScore[0];
// 3、遍历数组的每个元素,依次与最大值变量的数据比较,若较大,则替换。
for (int i = 1; i < faceScore.length; i++) {
if(faceScore[i] > max){
max = faceScore[i];
}
}
// 4、输出最大值变量存储的数据即可。
System.out.println("数组的最大值是:" + max);
}
}
猜数字游戏
游戏规则如下: 游戏后台随机生成1-20之间的5个数(无所谓是否重复),然后让大家来猜数字: 未猜中提示:“未命中”,并继续猜测 猜中提示:“运气不错,猜中了”,并输出该数据第一次出现的索引位置,最后把数组中的5个数据都输出看以下, 然后结束本游戏。
public class test10086 {
public static void main(String[] args) {
// 定义一个数组,用来存放随机数
int[] arr = new int[5];
// 生成 1-20 区间的五个随机数
for (int i = 0; i < 5; i++) {
Random random = new Random();
int j = random.nextInt(1, 21);
arr[i] = j;
}
// 控制台输出
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入一个 1-20 数字:");
int i = scanner.nextInt();
if (i == arr[0] || i == arr[1] || i == arr[2] || i == arr[3] || i == arr[4]) {
System.out.println("您已经猜中了该数据,运气不错了!您猜中的数据索引是:" + i);
// 遍历数组
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[j] + " ");
}
break;
} else if (i > 20 || i < 0) { //
System.out.println("输入有误,请重新输入!");
} else {
System.out.println("很遗憾,猜错了!");
}
}
}
}
随机排名经典
某公司开发部5名开发人员,要进行项目进展汇报演讲,现在采取随机排名后进行汇报。 请先依次录入5名员工的工号,然后展示出一组随机的排名顺序。
public class Test4 {
public static void main(String[] args) {
// 目标:键盘录入一组工号,最终要随机输出一组出来作为排名
Scanner sc = new Scanner(System.in);
System.out.println("输入需要多少个员工进行排序:" );
int a1 = sc.nextInt();
// 1、动态初始化一个数组
int[] codes = new int[a1]; // 动态生成
// 2、定义一个循环,循环5次,依次录入一个工号存入对应的位置
// Scanner sc = new Scanner(System.in);
for (int i = 0; i < codes.length; i++) {
// 正式录入工号
System.out.println("请您输入第" + (i + 1) + "个员工的工号:");
int code = sc.nextInt();
// 存入到数组中去
codes[i] = code;
}
// 3、遍历数组中的每个元素,然后随机一个索引出来,让该元素与随机索引位置处的元素值进行交换(本节的重点)
// codes = [12, 36, 28, 45, 99]
Random r = new Random();
for (int i = 0; i < codes.length; i++) {
// 当前遍历的元素值:codes[i]
// 随机一个索引位置出来:codes[index]
int index = r.nextInt(codes.length);
// 定义一个临时变量存储index位置处的值
int temp = codes[index];
codes[index] = codes[i];
codes[i] = temp;
}
// 4、遍历数组元素输出就是随机排名的结果
for (int i = 0; i < codes.length; i++) {
System.out.print(codes[i] + "t");
}
}
}
数组的内存图
Java内存分配
java内存分配
数组内存图数组内存分配
两个变量指向同一个数组- 赋的不是数组对象,而是地址
两个变量指向同一个数组对象
数组使用的常见问题 问题1:- 如果访问的元素位置超过最大索引,执行时会出现ArrayIndexOutOfBoundsException(数组索引越界异常)
- 如果数组变量中没有存储数组的地址,而是null, 在访问数组信息时会出现NullPointerException(空指针异常)
public class test10086 {
public static void main(String[] args) {
//数组角标越界的异常:ArrayIndexOutOfBoundsException
int[] arr = new int[]{1, 2, 3, 4, 5};
for (int i = 0; i <= arr.length; i++) { //多写个等号
System.out.println(arr[i]);
}
System.out.println(arr[-2]);
//空指针异常:NullPointerException
//情况一:
//情况二:
int[][] arr2 = new int[4][];
System.out.println(arr2[0][0]);
//情况三:
String[] arr3 = new String[]{null, "bb", "cc"};
System.out.println(arr3[0].toString());
//与上面表示的一样
String[] arr4 = new String[]{"aa", "bb", "cc"};
arr3[0] = null;
System.out.println(arr3[0].toString());
}
}
二维数组
public class test1 {
public static void main(String[] args) {
//1.二维数组的声明和初始化
int[] arr =new int[] {1,2,3};//一维数组
//静态初始化
int[][] arr1=new int[][]{{1,2,3},{4,5},{6,7}};//二维数组
//动态初始化1
String[][] arr2=new String[5][7];
//动态初始化2
String[][] arr3=new String[3][];
//同是正确写法:
int[] arr4[]=new int[][]{{1,2,3},{4,5},{6,7}};
int[] arr5[]={{1,2,3},{4,5},{6,7}};
//2.如何调用数组的指定位置的元素:
//静态
System.out.println(arr1[2][1]);//第一个[]表示第几个{}第二个[]表示括号里第几个数
System.out.println(arr1[0][2]);//特别注意:数组是从0开始的
arr3[1] =new String[4];
System.out.println(arr3[1][0]);//null
//3.如何获取数组的长度:
System.out.println(arr4.length);//表示数组里面有几个{}为数组的长度
System.out.println(arr4[0].length);//表示数组第一个{}里面数组的长度{1,2,3} 3
System.out.println(arr4[1].length);//表示数组第一个{}里面数组的长度{4,5} 2
//4.如何遍历二维数组
for(int i=0;i
for(int j=0;j
System.out.print(arr4[i][j]+" ");
}
System.out.println();
}
//5.数组元素默认的初始化值
}
}
public class test2 {
public static void main(String[] args) {
int[][] arr = new int [4][3];
System.out.println(arr[0]); //地址值[I@10dea4e [表示一维的 I表示int型
System.out.println(arr[0][0]);//0
System.out.println(arr);//[[I@647e05 二维的
System.out.println("*****************************");
float[][] arr1 = new float [4][3];
System.out.println(arr1[0]); //地址值
System.out.println(arr1[0][0]);//0.0
System.out.println("*******************");
String[][] arr2 = new String [4][2];
System.out.println(arr2[1]); //地址值
System.out.println(arr2[1][1]);//null
//特殊
System.out.println("*******************");
double[][] arr3 = new double [4][];
System.out.println(arr3[1]);//null
//System.out.println(arr3[1][0]);//报错:空指针异常
char [][] arr7 = new char [4][];
System.out.println(arr7[1]);
System.out.println("*");
}
}
数组的(面试题)
数组复制
// 数组的复制
public class Copy {
public static void main(String[] args) {
// 数组的复制
int[] a1, a2;
a1 = new int[]{2, 3, 5, 7, 11, 13, 17, 19};
for (int i = 0; i < a1.length; i++) {
System.out.print(a1[i] + " ");
}
//赋值a2变量等于a1
//数组的复制:
a2 = new int[a1.length];
for (int i = 0; i < a2.length; i++) {
a2[i] = a1[i];
}
//修改a2中的偶索引元素,使其等于索引(如a[0]=0,a[2]=2)打印出a1
for (int i = 0; i < a1.length; i++) {
if (i % 2 == 0) {
a2[i] = i;
}
}
System.out.println();
//打印a1
for (int i = 0; i < a1.length; i++) {
System.out.print(a2[i] + " ");
}
System.out.println();
System.out.println(a1);// [I@58372a00
System.out.println(a2);// [I@4dd8dc3
System.out.println("***************");
String[] arr = new String[]{"AA", "BB", "CC", "DD", "EE"};
//数组的复制(区别于数组变量的赋值:arr1=arr)
String[] arr1 = new String[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
System.out.print(arr1[i] + " ");
}
System.out.println();
System.out.println("***************");
System.out.println(arr1); // [Ljava.lang.String;@568db2f2
System.out.println(arr); //[Ljava.lang.String;@378bf509
}
}
数组反转
// 数组的反转
public class Reversal {
public static void main(String[] args) {
String[] arr = new String[]{"AA", "BB", "CC", "DD", "EE"};
// 数组的反转
// 方式一:
System.out.println("方式一: ");
for (int i = 0; i < arr.length / 2; i++) {
String temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
for (int i = 0; i < arr.length; i++) { // EE DD CC BB AA
System.out.print(arr[i] + " ");
}
//方法一的优化
System.out.println();
System.out.println("方法一的优化 ");
for (int j = 0; j < arr.length; j++) {//遍历 AA DD CC BB EE
for (int i = 0; i <= 0; i++) {
String temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
System.out.print(arr[j] + " ");
}
// 方式二
System.out.println();
System.out.println("方式二 : ");
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
String temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//遍历
for (int i = 0; i < arr.length; i++) { //EE BB CC DD AA
System.out.print(arr[i] + " ");
}
}
}
数组排序(面试题冒泡排序)
- 就是对数组中的元素,进行升序(由小到大)或者降序(由大到小)的操作。
public class Sort {
public static void main(String[] args) {
int[] arr = new int[]{43, 25, 74, 78, -59, -89, -56, 78, 15};
//冒泡排序
for (int i = 0; i < arr.length - 1; i++) { //第几大轮 特别注意:这里的i是控制循环次数的,不是数组下标 从 0 开始 次数是 arr.length - 1
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
//理解
//i=0 1轮 j
//arr.length-2=arr[j] arr[j+1]=arr.length-1 索引为大值
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
{
}
}
}
}
总结
-
冒泡排序的思想
- 从头开始两两比较,把较大的元素与较小的元素进行交换
- 每轮把当前最大的一个元素存入到数组当前的末尾。
-
冒泡排序的实现步骤。
- 定义一个外部循环控制总共需要冒几轮(数组的长度-1)
- 定义一个内部循环,控制每轮依次往后比较几个位置(数组长度-i-1)。
// 数组的查找 : 二分查找
public class LoopUp {
public static void main(String[] args) {
String[] arr = new String[]{"AA", "BB", "CC", "DD", "EE"};
//数组的查找:线性查找,二分法查找
//线性查找:从头往后查找
String dest = "BB";
boolean isFlag = true;
for (int i = 0; i < arr.length; i++) {
if (dest.equals(arr[i])) { //字符串是equals int型用==就可以
System.out.println("找到了指定的元素,位置为" + i);
isFlag = false;
break;
}
}
if (isFlag) {
System.out.println("很遗憾没有找到来");
}
}
}
二分查找
// 数组的查找 : 二分查找
public class LoopUp {
public static void main(String[] args) {
//二分法查找:折半查找 比较快
//前提:所要查找的数组要有序
int[] arr2 = new int[]{-98, -65, -34, -32, 0, 15, 48, 79, 89, 333, 456, 789};
int dest1 = -34;
int head = 0;//初始的首索引
int end = arr2.length - 1;//初始的末索引
boolean isFlag1 = true;
while (head <= end) {
int middle = (head + end) / 2;//middle中间值
if (dest1 == arr2[middle]) {
System.out.println("找到指定得到元素,位置为" + middle);
isFlag = false;
break;
} else if (arr2[middle] > dest1) { //中间值比所要找的值大 ——————|————————在左面区域
end = middle - 1;
} else {//arr2[middle]>dest1) //中间值比所要找的值小 ——————|————————在右面区域
head = middle + 1;
}
}
if (isFlag) {
System.out.println("没有找到该元素哦!");
}
}
}



