第4天 java基础语法
1. 数组介绍及动态初始化
1.1 数组的概述和定义格式
1.1.1 数组的概述
数组是存储多个变量(元素)的东西(容器)
这多个变量的数据类型要一致
1.1.2 数组概念
数组是存储同一种数据类型多个元素的容器。
数组既可以存储基本数据类型,也可以存储引用数据类型。
1.1.3 数组的定义格式
格式1:数据类型[] 数组名;
格式2:数据类型 数组名[];
注意:这两种定义做完了,数组中是没有元素值的。如何对数组的元素进行初始化呢?
1.2 数组初始化之动态初始化
1.2.1 数组初始化概述
Java中的数组必须先初始化,然后才能使用。
所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。
1.2.2 数组初始化之动态初始化
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值。
格式:数据类型[] 数组名 = new 数据类型[数组长度];
数组长度其实就是数组中元素的个数。
举例:
int[] arr = new int[3];
解释:定义了一个int类型的数组,这个数组中可以存放3个int类型的值。
1.3 数组操作之获取数组中的元素
package day04;
/*
* 数组:存储同一种数据类型元素的容器
*
* 定义格式:
* 第一种 数据类型[] 数组名;
* 第二种 数据类型 数组名[];
* 举例:
*
* int[] arr 定义了一个int类型的数组,数组名为arr
* int arr[] 定义了一个int类型的变量,变量名为arr[]
*
*数组的初始化:所谓初始化其实就是为数组开辟内存空间,并为数组中的每一个元素赋予初始值
* 1.动态初始化值:只给出长度,由系统给出初始化值
* 2.静态初始化值:只给初始化值,由系统决定长度
* 动态初始化值格式: 数据类型[] 数组名 = new 数据类型[数据长度]
* */
public class MyArrayTest01 {
public static void main(String[] args) {
int[] arr = new int[3];
/*
* 左边: int表示数组中的元素类型为int类型
* []代表数组
* arr表示数组的名称
*
* 右边:new表示开辟内存空间
* int表示数组中的元素类型为int类型
* []表示数组
* 3:数组长度,其实就是数组中元素的个数
*
* */
//输出数组名
System.out.println("arr:" + arr);//arr:[I@4554617c
System.out.println("arr[0]"+ arr[0]); //0
System.out.println("arr[1]"+ arr[1]); //0
System.out.println("arr[2]"+ arr[2]); //0
}
}
2.数组内存结构及静态初始化
2.1 JVM内存划分
Java 程序在运行时,需要在内存中的分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
栈 存储局部变量
堆 存储new出来的东西
方法区 (面向对象进阶讲)
本地方法区 (和系统相关)
寄存器 (给CPU使用)
2.2 一个数组的内存图
定义一个数组,输出数组名及元素。然后给数组中的元素赋值,再次输出数组名及元素
2.2.1案例代码
package day04;
/*
* 定义一个数组,输出数组名及元素。然后给数组中的元素赋值
* ,再次输出数组名及元素
*
*
*
* */
public class MyArrayTest02 {
public static void main(String[] args) {
//定义一个数组,输出数组名及元素
int []arr = new int[3];
System.out.println("arr:" + arr);
System.out.println("arr[0]:" + arr[0]);
System.out.println("arr[1]:" + arr[1]);
System.out.println("arr[2]:" + arr[2]);
System.out.println("------------------");
//给数组中的元素赋值
arr[0] = 150;
arr[2] = 250;
//再次输出数组名及元素
System.out.println("arr:" + arr);
System.out.println("arr[0]:" + arr[0]);
System.out.println("arr[1]:" + arr[1]);
System.out.println("arr[2]:" + arr[2]);
}
}
2.3 二个数组的内存图
定义两个数组,分别输出数组名及元素。然后分别给数组中的元素赋值,分别再次输出数组名及元素
2.3.1 案例代码
package day04;
/*
*
* 定义两个数组,分别输出数组名及元素。
* 然后分别给数组中的元素赋值,分别再次输出数组名及元素
*
*
*
* */
public class MyArrayTest03 {
public static void main(String[] args) {
//定义两个数组,分别输出数组名及元素
int[]arr = new int[2];
int[]arr2 = new int[3];
System.out.println("arr:" + arr);
System.out.println("arr[0]:" + arr[0]);
System.out.println("arr[1]:" + arr[1]);
System.out.println("arr2:" + arr2);
System.out.println("arr2[0]:" + arr2[0]);
System.out.println("arr2[1]:" + arr2[1]);
System.out.println("arr2[1]:" + arr2[2]);
System.out.println("--------------------");
//分别给数组中的元素赋值
arr[1] = 100;
arr2[1] = 200;
arr2[2] = 400;
//再次输出数组名及元素
System.out.println("arr:" + arr);
System.out.println("arr[0]:" + arr[0]);
System.out.println("arr[1]:" + arr[1]);
System.out.println("arr2:" + arr2);
System.out.println("arr2[0]:" + arr2[0]);
System.out.println("arr2[1]:" + arr2[1]);
System.out.println("arr2[1]:" + arr2[2]);
}
}
2.4 二个数组指向同一个堆内存的内存图
定义两个数组,先定义一个数组,赋值,输出。然后定义第二个数组的时候把第一个数组的地址赋值给第二个数组。然后给第二个数组赋值,再次输出两个数组的名及元素
2.4.1案例代码
package day04;
/*
* 定义两个数组,先定义一个数组,赋值,输出。然后定义第二个数组的时候把第一个数组的地址赋值给第二个数组。
* 然后给第二个数组赋值,再次输出两个数组的名及元素
*
*
*
* */
public class MyArrayTest04 {
public static void main(String[] args) {
//先定义一个数组,赋值,输出
int []arr = new int[3];
arr[0] = 100;
arr[1] = 300;
arr[2] = 300;
System.out.println("arr" + arr);
System.out.println("arr[0]"+ arr[0]);
System.out.println("arr[1]"+ arr[1]);
System.out.println("arr[2]"+ arr[2]);
System.out.println("----------------");
//然后定义第二个数组的时候把第一个数组的地址赋值给第二个数组
int []arr2 = arr;
//然后给第二个数组赋值
arr2[0] = 120;
arr2[1] = 400;
arr2[2] = 300;
//再次输出两个数组的名及元素
System.out.println("arr" + arr);
System.out.println("arr[0]" + arr[0]);
System.out.println("arr[1]" + arr[1]);
System.out.println("arr[2]" + arr[2]);
System.out.println("--------------");
System.out.println("arr2:" + arr2);
System.out.println("arr2[0]" + arr2[0]);
System.out.println("arr2[1]" + arr2[1]);
System.out.println("arr2[2]" + arr2[2]);
}
}
2.5 数组初始化之静态初始化
静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度。
格式:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
举例:
int[] arr = new int[]{1,2,3};
解释:定义了一个int类型的数组,这个数组中可以存放3个int类型的值,并且值分别是1,2,3 其实这种写法还有一个简化的写法
int[] arr = {1,2,3};
2.5.1案例代码
package day04;
/*
* 数组静态初始化:初始化时指定每个元素的初始值,由系统决定数组长度
* 格式: 数据类型[] 数组名 = 数据类型[]{元素1,元素2,....};
* 简化格式
* 举例 数据类型[]数组名 = {元素1,元素2,...}
*
*
*
* */
public class MyArrayTest05 {
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println("arr:" + arr);
System.out.println("arr[0]" + arr[0]);
System.out.println("arr[1]" + arr[1]);
System.out.println("arr[2]" + arr[2]);
}
}
3.数组常见问题及练习
3.1 数组的元素访问
package day04;
/*
* 数组:存储同一种数据类型元素的容器
*
* 定义格式:
* 第一种 数据类型[] 数组名;
* 第二种 数据类型 数组名[];
* 举例:
*
* int[] arr 定义了一个int类型的数组,数组名为arr
* int arr[] 定义了一个int类型的变量,变量名为arr[]
*
*数组的初始化:所谓初始化其实就是为数组开辟内存空间,并为数组中的每一个元素赋予初始值
* 1.动态初始化值:只给出长度,由系统给出初始化值
* 2.静态初始化值:只给初始化值,由系统决定长度
* 动态初始化值格式: 数据类型[] 数组名 = new 数据类型[数据长度]
* */
public class MyArrayTest01 {
public static void main(String[] args) {
//数据类型[] 数组名 = new 数据类型[数据长度]
int[] arr = new int[3];
/*
* 左边: int表示数组中的元素类型为int类型
* []代表数组
* arr表示数组的名称
*
* 右边:new表示开辟内存空间
* int表示数组中的元素类型为int类型
* []表示数组
* 3:数组长度,其实就是数组中元素的个数
*
*
* */
//输出数组名
System.out.println("arr:" + arr);//arr:[I@4554617c
//我们获取到地址值没有意义,我要的是数组中的数据值,该怎么办呢?
//不用担心,java已经帮你想好了
//其实数组中的每个元素都是有编号的,编号是从0开始的,最大的编号就是数组的长度-1
//用数组名和编号的配合我们就可以获取数组中的指定编号的元素
//这个编号的专业叫法:索引
//格式:数组名[编号] -- 数组名[索引]
System.out.println("arr[0]"+ arr[0]); //0
System.out.println("arr[1]"+ arr[1]); //0
System.out.println("arr[2]"+ arr[2]); //0
}
}
3.2 数组操作的两个常见小问题
package day04;
/*
* 两个常见问题:1.ArrayIndexOutOfBoundsException
* 数组索引越界异常 为什么会产生呢?我们访问了不存在的索引
* 2.NullPointerException
* 空指针异常 为什么会产生呢?指不再指向堆内存中的数据,二我们还在访问内存中的数
*
* */
public class MyArrayTest06 {
public static void main(String[] args) {
//定义数组
int[] arr = {1, 2, 3};
//访问数组元素
System.out.println(arr[2]);
//引用数据类型:类,接口,数组
//常量:null,它可以赋值给引用数据类型,表示不再指向对内存中的数据
arr = null;
System.out.println(arr[2]);
}
}
3.3 数组操作之遍历数组
package day04;
/*
*
* 需求:数组遍历(依次输出数组中的每一个元素)
*
*
*
* */
public class MyArrayTest07 {
public static void main(String[] args) {
//定义一个数组
int[] arr = {1, 2, 3, 4, 5};
//输出数组元素
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]);
System.out.println("----------");
//用for循环获取0-4的数据
for (int i = 0; i < 5; i++) {
System.out.println(arr[i]);
}
System.out.println("----------");
//未来解决我们去数数组元素个数的问题,数组提供了一个属性length
//用于获取数组中元素的个数 格式:数组名.length
//用for循环改进
System.out.println("arr数组共有"+arr.length+ "个元素");
//数组遍历的标准版代码
for(int i = 0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
3.4 数组操作之获取最值
package day04;
/*
* 求数组元素中的最大最小值
*
*
* */
public class MaxAndMinTest {
public static void main(String[] args) {
//定义一个数组元素
int[] arr = {73, 67, 93, 21, 19};
//定义一个参照物
int max = arr[0];
for (int x = 1; x < arr.length; x++) {
if (arr[x] > max) {
max = arr[x];//如果元素的值大于参照物,就留下来做参照物
}
}
System.out.println("max:" + max);
System.out.println("--------------");
//定义一个参照物
int min = arr[0];
for (int i = 1; i< arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
System.out.println("min:" + min);
}
}
3.5 数组练习之评委打分
package day04;
import java.util.Scanner;
/*
* 需求:在编程竞赛中,有6个评委为参赛的选手打分,分数为0-100的整数分。
选手的最后得分为:去掉一个最高分和一个最低分后 的4个评委平均值。
请写代码实现。(不考虑小数部分)
分析:1.定义一个长度为6的数组
* 2.评委打分是的分数采用键盘录入
* 3.获取最高分
* 4.获取最低分
* 5.获取总分
* 6.计算平均分(总分-最高分-最低分)/(arr.length-2)
* 7.输出平均分
*
*
*
* */
public class MyArrayTest08 {
public static void main(String[] args) {
//定义一个长度为6的数组
int[] arr = new int[6];
//评委打分是的分数采用键盘录入
Scanner sc = new Scanner(System.in);
for (int x = 0; x < arr.length; x++) {
System.out.println("请输入第" + (x+1) + "个给出的的分数:");
int score = sc.nextInt();
arr[x] = score;
}
// 获取最高分
int max = arr[0];
for (int x = 1; x < arr.length; x++) {
if (arr[x] > max) {
max = arr[x];
}
}
//获取最低分
int min = arr[0];
for (int x = 1; x < arr.length; x++) {
if (arr[x] < min) {
min = arr[x];
}
}
//获取总分
int sum = 0;
for (int x = 0; x < arr.length; x++) {
sum += arr[x];
}
//计算平均分(总分-最高分-最低分)/(arr.length-2)
int avg = (sum-max-min)/(arr.length-2);
//输出平均分
System.out.println("该选手的最终得分为:" + avg);
}
}
3.6 数组练习之不死神兔
package day04;
/*
* 需求:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,
* 假如兔子都不死,问第二十个月的兔子对数为多少?
*
* 规律:
* 第一个月:1
* 第二个月:1
* 第三个月:2
* 第四个月:3
* 第五个月:5
* ...
* 从第三月开始,每月的兔子对数是前面两个月的对数之和
* 第一个月和第二个月的兔子对数都为1
*
* 分析:
* 1:由于数据比较多,所以我们定义数组实现
* int[] arr = new int[20];
* 2:给数组中的元素赋值
* arr[0] = 1;
* arr[1] = 1;
* 3:从第三个月开始,根据规律赋值
* arr[2] = arr[1] + arr[0];
* arr[3] = arr[2] + arr[1];
* arr[4] = arr[3] + arr[2];
* ...
* 4:输出第二十个月的兔子对数,其实就是输出arr[19];
*
*
* */
public class MyArrayTest09 {
public static void main(String[] args) {
//定义一个数组
int[] arr = new int[20];
//给数组中的元素赋值
arr[0] = 1;
arr[1] = 1;
//从第三月个月开始,规律赋值
for (int x = 2; x < arr.length; x++) {
arr[x] = arr[x-1] + arr[x-2];
}
输出第二十个月的兔子对数,其实就是输出arr[19]
System.out.println("第二十个月的兔子对数为:"+ arr[19]);
}
}