第一章 流程控制语句
1.1选择结构switch
它和if条件语句不同,它只能针对某个表达式的值作出判断,从而决定程序执行哪一段代码。
switch (表达式){
case 目标值1:
执行语句1
break;
case 目标值2:
执行语句2
break;
......
case 目标值n:
执行语句n
break;
default:
执行语句n+1
break;
}
在上面的格式中,switch语句将表达式的值与每个case中的目标值进行匹配,如果找到了匹配的值,会执行对应case后的语句,遇到break,就全结束。
如果没找到任何匹配的值,就会执行default后的语句。
1.2switch的穿透性
若case 后面没有break, 程序就会一直向下穿透。
package day4;
public class SwitchDemo_1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int week = 3;
switch(week){
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("工作日");
break;
case 6:
case 7:
System.out.println("休息日");
break;
}
}
}
结果:
补充:
switch语句中的表达式的数据类型是有要求的:
- JDK1.0 - 1.4 数据类型接受 byte short int char
- JDK 1.5 数据类型接受byte short int char enum(枚举)
- JDK1.7数据类型接受byte short int char enum(枚举) String
enum weekday {sun, mou, tue, wed, thu, fri, sat } ;
该枚举名为weekday,枚举元素有7个,凡是被说明为weekday类型变量的取值只能是7天中的某一个值。
第二章 数组
数组是指一组数据的集合,数组中的每个数据被称作元素。在数组中可以存放任意类型的元素,但同一个数组里存放的元素类型必须一致。
2.1数组的定义
数组定义格式:
- 数据类型[] 数组名 = new 数据类型[元素个数/数组长度]
- 例如:int[] a= new int[10]//其为引用数据类型,因此使用new
为了更好地理解数组的这种定义方式,可以将上面的一句代码分成两句来写,具体如下:
- int[] x; // 声明一个int[]类型的变量
- x = new int[100]; // 创建一个长度为100的数组
所有的硬件由操作系统管理,java程序在jvm上执行,则jvm将向操作系统申请内存。
操作系统分给jvm64M的内存,jvm又将内存进行划分,分为5个区域。
JVM内存划分:
- 寄存器:内存与cpu之间的操作。
- 本地方法栈:有些功能jvm完成不了,需要调用操作系统的中的功能。
- 方法和数据共享区:运行时期.class文件进入内存的地方。(程序运行的是.class文件)
- 方法栈:所有的方法运行的时候,进入的内存区域。(程序运行时main方法存储的地方)
- 堆:存储的是容器和对象
申请与清理内存jvm将自己完成,不需要程序开发者完成。但c++中,开辟空间不需要开发者,清理内存需要开发者完成。
运行一个.class文件,其在内存中的操作:
- 首先.class文件进入方法数据共享区
- 其次,main方法进入方法栈,即入栈运行(也称压栈运行)
- JVM在堆内存开辟空间,存储数组容器。因此数组就有了内存地址(假设为首地址为0xAB)
- JVM将数组首地址(0xAB)传给变量arr。(这也是arr为引用类型的原因,变量中存储的是变量地址,而不是值。)
因为数组内部在内存中是连续的,因此找到第一个地址,就能找到之后元素的地址。
当main运行结束是,arr也就没有了,因此我们是不需要参与内存清理的。
数组的内存图:
public class ArrayDemo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[10];
System.out.println(arr); //[I@15db9742,@是分隔符,后面的15db9742是16进制的内存地址
}
}
结果:
每次运行的结果可能不一样,因为虚拟机每次开的内存地址不一样。
- int型数组默认值为0,这是因为当数组被成功创建后,数组中元素会被自动赋予一个默认值。
- 数组中的每个元素都有一个索引(也可称为角标),要想访问数组中的元素可以通过x[0]、x[1]的形式。
- 需要注意的是,数组中最小的索引是0,最大的索引是“数组的长度-1”。
在Java中,为了方便我们获得数组的长度,提供了一个length属性。
- 获得数组的长度的方法:数组名.length
- 数组类型为:int
- 数组最大索引为:数组名.length-1(减1,是因为数组标号从0开始)
数组定义的两种方式:
- 动态初始化:在定义数组时只指定数组长度,由系统为元素赋初值。
- 静态初始化:定义数组的同时,就为数组每个元素赋值。
两种静态初始化的方式:
- 类型[ ] 数组名 = new 类型[ ] {元素,元素,......};
int[] arr2 = new int[] {1,2,3,4};
- 类型[ ] 数组名 = {元素,元素,......};
int[] arr1 = {1,2,3};
public class ArrayDemo01 {
public static void main(String[] args) {
//静态
int[] arr1 = {1,2,3};
System.out.println(arr1[2]);
//静态,此种易错,不推荐使用
int[] arr2 = new int[] {1,2,3,4};
System.out.println(arr2[0]);
}
}
结果:
2.2 数组的遍历
遍历:依次访问数组中的每个元素
public class ArrayDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {1,2,3,4,5,6,7};
for(int i =0;i<arr.length;i++) {
System.out.println(arr[i]);
}
}
}
结果:
2.3数组常见问题
数组的异常
- 数组的索引越界异常(ArrayIndexOutOfBoundsException)
- 空指针异常(NullPointerException)
2.3.1越界异常
public class ArrayDemo_1 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7};
System.out.println(arr[9]);
}
}
结果:
2.3.2空指针异常
public class ArrayDemo_1 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7};
System.out.println(arr);
arr = null ;
System.out.println(arr[2]);
}
}
结果:
2.3.3数组空指针异常图
2.3.4 输出数组中的最大值
寻找最大值思路图:
public class ArrayDemo_2 {
public static void main(String[] args) {
//找数组中的最大值
int[] arr = {1,11,6,9,5,3,18};
int max = arr[0];
for(int i =1;i<arr.length;i++) {
if (arr[i]>max) {
max = arr[i];
}
}
System.out.println(max);
}
}
结果:
2.4二维数组
二维数组:数组中的数组,数组中存储的还是数组。二维数组存的是每个数组的首地址。
2.4.1二维数组存储图:
2.4.2二维数组的定义
定义方式:
方法一:
int[ ][ ] arr = new int[3][4]; //定义了一个三行四列的数组[3]表示:二维数组中,有三个一维数组。
[4]表示:三个一位数组中,每个数组的长度都是4。
方法二://不推荐
int[][] arr = new int[3][];
arr[0]= new int[1];//必须要new
arr[1]= new int[2];
arr[1]= new int[3];
方法三://最简单的定义方式
int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
2.4.3二维数组越界
public class ArrayArrayDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
System.out.println(arr[2][3]);//越界
}
}
结果:
2.4.4二维数组的遍历
public class ArrayArrayDemo_1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
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();
}
}
}
结果:
2.4.5 举例1
统计一个公司三个销售小组中每个小组的总销售额以及整个公司的销售额。如下所示
- 第一小组销售额为{11, 12}万元
- 第二小组销售额为{21, 22, 23}万元
- 第三小组销售额为{31, 32, 33, 34}万元。
public class ArrayArrayDemo_2 {
public static void main(String[] args) {
int sum = 0;//总销售额
// TODO Auto-generated method stub
int[][] arr = {{11, 12},{21, 22, 23},{31, 32, 33, 34}};
for(int i=0;i<arr.length;i++) {
int groupSum=0;// 每个小组的销售额
for(int j=0;j<arr[i].length;j++) {
groupSum+= arr[i][j];
}
System.out.println("第"+(i+1)+"个小组营业额为:"+groupSum);
sum+=groupSum;
}
System.out.println("总营业额为:"+sum);
}
}
结果:
2.4.6 举例2
随机点名器,即在全班同学中随机的打印出一名同学名字。
import java.util.Random;
import java.util.Scanner;
public class CallName {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] names = {"张三","李四","王五","李蕾","韩梅梅","小名","老王","小华","约翰逊","爱丽丝"};
System.out.println("输入1,查询所有人名");
System.out.println("输入2,随机选一个人名");
System.out.println("请输入:");
Scanner scan = new Scanner(System.in);
int sc = scan.nextInt();
switch (sc) {
case 1:{
//1.查看所有同学名字
for(int j= 0;j<names.length;j++) {
System.out.print(names[j]+" ");
}
System.out.println();
break;
}
case 2:{
//2.随机选一个人
Random ran = new Random();
int r = ran.nextInt(names.length)+1;
System.out.println("第"+r+"位同学为:"+names[r-1]);
break;
}
}
}
}
结果: