尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)
开发环境:jdk17 + idea2022
第一阶段:Java基本语法
一、Java语言概述
01、Java新版视频教程简介
02、课程目录说明
03、Java基础全栈学习路线
04、抽茧剥丝话Java
05、Java工程师全程学习路线
06、计算机硬件的介绍
6.1 计算机组成:硬件+软件
6.2 CPU、内存与硬盘
6.3 输入设备:键盘输入
金山打字通
07、常见的DOS命令
DOS(Disk Operating System,磁盘操作系统)是Microsoft公司在Windows之前推出的一个操作系统,是单用户、单任务(即只能执行一个任务)的操作系统。现在被Windows系统取代。
进入DOS操作窗口:
按下Windows+R键盘,打开运行窗口,输入cmd回车,进入到DOS的操作窗口。
常用指令:
操作1:进入和回退
操作 说明
盘符名称: 盘符切换。E:回车,表示切换到E盘。
dir 列出当前目录下的文件以及文件夹
cd 目录 进入指定单级目录。
cd 目录1\目录2\... 进入指定多级目录。cd atguigu\JavaSE
cd .. 回退到上一级目录。
cd \ 或 cd / 回退到盘符目录。
操作2:增、删
操作 说明
md 文件目录名 创建指定的文件目录。
rd 文件目录名 删除指定的文件目录(如文件目录内有数据,删除失败)
操作3:其它
操作 说明
cls 清屏。
exit 退出命令提示符窗口。
← → 移动光标
↑ ↓ 调阅历史操作命令
Delete和Backspace 删除字符
08、不同编程语言的介绍
8.1 计算机语言是什么
就是人与计算机交流的方式。人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功能。
计算机语言有很多种。如:C 、C++、Java、Go、JavaScript、Python,Scala等。
8.2 计算机语言简史
高级语言独立于机器,有一定的通用性;计算机不能直接识别和执行用高级语言编写的程序,需要使用编译器或者解释器,转换为机器语言才能被识别和执行
高级语言按照程序设计方法的不同,又分为:面向过程的语言、面向对象的语言。
- 1.C、Pascal、Fortran面向过程的语言
- 2.C++面向过程/面向对象
- 3.Java跨平台的纯面向对象的语言
- 4.C#、Python、JavaScript、Scala…
8.3 计算机语言排行榜
TIOBE (https://www.tiobe.com/tiobe-index/)流行编程语言排行,每月更新
网传的编程语言鄙视链:
09、Java相关历史
10、JDK的选择和下载
path 路径从上往下识别
11、 HelloWorld
11.1 开发步骤
Java程序开发三步骤:编写、编译、运行。
- 将 Java 代码编写到扩展名为 .java 的源文件中
- 通过 javac.exe 命令对该 java 文件进行编译,生成一个或多个字节码文件
- 通过 java.exe 命令对生成的 class 文件进行运行
HelloWorld
cmd 复制路径 右击粘贴
新建文件,后缀为 .java
内容
编码格式 – ANSI
// 类 类名{}
class HelloChina{
}
cmd
C:\Users\stu>e:
E:\>cd E:\z_teach\javacode\chapter01
E:\z_teach\javacode\chapter01>javac HelloWorld.java
结果
cmd
E:\z_teach\javacode\chapter01>java HelloChina
错误: 在类 HelloChina 中找不到 main 方法, 请将 main 方法定义为:
public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application
内容
class HelloChina{
public static void main(String[] args){
}
}
重新运行
E:\z_teach\javacode\chapter01>javac HelloWorld.java
E:\z_teach\javacode\chapter01>java HelloChina
E:\z_teach\javacode\chapter01>
内容
class HelloChina{
public static void main(String[] args){
System.out.println("hello,world!!");
System.out.println("你好,中国!!");
}
}
重新运行
E:\z_teach\javacode\chapter01>javac HelloWorld.java
E:\z_teach\javacode\chapter01>java HelloChina
hello,world!!
你好,中国!!
内容
class HelloChina{
public static void main(String[] args){
System.out.println("hello,world!!");
System.out.println("你好,中国!!");
}
}
class Lin{
}
class Yu{
}
重新运行
E:\z_teach\javacode\chapter01>javac HelloWorld.java
结果
12.、HelloWorld总结
13、注释
内容
/*
这是多行注释,可以声明多行注释的信息
1、Java中的注释的种类:
单行注释、多行注释、文档注释(Java特有)
2、单行注释、多行注释的作用:
①对程序中的代码进行解释说明
②对程序进行调试
3、注意:
① 单行注释和多行注释声明的信息不参与编译。换句话说,编译后声明的字节码文件中不包含单行注释和多行注释的信息
② 多行注释不能嵌套使用
4、文档注释
文档注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档。
*/
/**
这是我的第一个java程序
@author davina
@version 1.0
*/
public class CommentTest{
/**
这是main方法,格式是固定的
*/
/**
这是main方法,格式是固定的(多行注释)
*/
public static void main(String[] args){
//这是输出语句
System.out.println("hello,world");
}
}
运行
E:\z_teach\javacode\chapter01>javadoc -d mydoc -author -version CommentTest.java
结果
14、 Java API文档
•下载API文档:
- 在线看:https://docs.oracle.com/en/java/javase/17/docs/api/index.html
- 离线下载:https://www.oracle.com/java/technologies/javase-jdk17-doc-downloads.html
15、Java核心机制:JVM
15.1 Java语言的优缺点
15.1.1 优点
跨平台性
面向对象性:
面向对象编程支持封装、继承、多态等特性,让程序更好达到高内聚,低耦合的标准。
健壮性
吸收了C/C++语言的优点,但去掉了其影响程序健壮性的部分(如指针、内存的申请与释放等),提供了一个相对安全的内存管理和访问机制
15.1.2 缺点
- 语法过于复杂、严谨,对程序员的约束比较多,与python、php等相比入门较难。但是一旦学会了,就业岗位需求量大,而且薪资待遇节节攀升。
- 一般适用于大型网站开发,整个架构会比较重,对于初创公司开发和维护人员的成本比较高(即薪资高),选择用Java语言开发网站或应用系统的需要一定的经济实力。
- 并非适用于所有领域
15.2 JVM功能说明
JVM(Java Virtual Machine ,Java虚拟机):是一个虚拟的计算机,是Java程序的运行环境。JVM具有指令集并使用不同的存储区域,负责执行指令,管理数据、内存、寄存器。
15.2.1 功能1:实现Java程序的跨平台性
我们编写的Java代码,都运行在JVM 之上。正是因为有了JVM,才使得Java程序具备了跨平台性。
使用JVM前后对比:
15.2.2 功能2:自动内存管理(内存分配、内存回收)
•Java程序在运行过程中,涉及到运算的数据的分配、存储等都由JVM来完成
•Java消除了程序员回收无用内存空间的职责。提供了一种系统级线程跟踪存储空间的分配情况,在内存空间达到相应阈值时,检查并释放可被释放的存储器空间。
•GC的自动回收,提高了内存空间的利用效率,也提高了编程人员的效率,很大程度上减少了因为没有释放空间而导致的内存泄漏。
16、章节案例
案例1:个人信息输出
内容
class PersonalInfo{
public static void main(String[] args){
System.out.println("姓名:康师傅");
System.out.println(); //换行
System.out.println("性别:男");
System.out.println("家庭住址:北京程序员聚集地:回龙观");
}
}
结果
E:\z_teach\javacode\chapter01>javac PersonalInfo.java
E:\z_teach\javacode\chapter01>java PersonalInfo
姓名:康师傅
性别:男
家庭住址:北京程序员聚集地:回龙观
E:\z_teach\javacode\chapter01>
案例2:输出:心形
结合\n(换行),\t(制表符),空格等在控制台打印出如下图所示的效果。
方式一:
//方式一:
class Exercise2{
public static void main(String[] args){
System.out.print("\t");
System.out.print("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.println("*");
System.out.print("*");
System.out.print("\t");
//System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("I love java");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.println("*");
System.out.print("\t");
System.out.print("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.println("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.println("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.println("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("*");
System.out.print("\t");
System.out.println("*");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print("\t");
System.out.print(" ");
System.out.print("*");
}
}
方式二:
class Exercise3{
public static void main(String[] args){
System.out.print("\t"+"*"+"\t\t\t\t\t\t\t\t\t\t\t\t"+"*"+"\t"+"\n");
System.out.print("*"+"\t\t"+"*"+"\t\t\t\t"+"I love Java"+"\t\t\t\t"+"*"+"\t\t\t"+"*"+"\n");
System.out.print("\t"+"*"+"\t\t\t\t\t\t\t\t\t\t\t\t"+"*"+"\t"+"\n");
System.out.print("\t\t"+"*"+"\t\t\t\t\t\t\t\t\t\t"+"*"+"\t\t"+"\n");
System.out.print("\t\t\t"+"*"+"\t\t\t\t\t\t\t\t"+"*"+"\t"+"\n");
System.out.print("\t\t\t\t"+"*"+"\t\t\t\t\t\t"+"*"+""+"\t"+"\n");
System.out.print("\t\t\t\t\t"+"*"+"\t\t\t\t"+"*"+""+"\t\t"+"\n");
System.out.print("\t\t\t\t\t\t"+"*"+"\t\t"+"*"+""+"\t\t"+"\n");
System.out.print("\t\t\t\t\t\t\t"+"*"+"\n");
}
}
17、随堂复习与企业真题
17.1、随堂复习
17.1.1、java基础全程的学习内容
神书:《Java核心技术》、《effective java》、《java编程思想》
17.1.2、软件开发相关内容
没有最好的语言,只有在特地场景下相对来说,最适合的语言
17.1.3、java概述
17.1.4、Java环境的搭建
17.1.5、代码
17.1.6、常见问题
17.1.7、API文档
17.1.8、练习
17.2、企业真题
1、一个“.java”源文件中是否可以包括多个类?有什么限制(明*数据)
一个源文件中可以声明多个类,最多只有一个类使用public 进行声明。
但是一个源文件只能有一个public的类
2、java的优势()
- 跨平台型
- 安全性高
- 简单性
- 高性能
- 面向对象性
- 健壮性
3、常用的几个命令行操作都有哪些(至少4个)
4、java中是否存在内存溢出、内存泄漏?如何解决?举例说明(拼)**
存在
不能
5. 如何看待Java是一门半编译半解释型的语言
二、变量与运算符
01、关键字、保留字
- 定义:被Java语言赋予了特殊含义,用做专门用途的字符串(或单词)HelloWorld案例中,出现的关键字有 class、public 、 static 、 void 等,这些单词已经被Java定义好了。
特点:全部关键字都是小写字母。
关键字比较多,不需要死记硬背,学到哪里记到哪里即可。
说明:
1.关键字一共50个,其中const和goto是保留字(reserved word)。
2.true,false,null不是关键字,是字面量,表示特殊的布尔值和空值,可以当做关键字来看待
保留字 :const、goto
02. 标识符( identifier)
- 凡是自己可以起名字的地方都叫标识符。
- 比如:类名、变量名、方法名、接口名、包名、常量名
2.1、标识符的命名规则(必须遵守的硬性规定):
- 由26个英文字母大小写,0-9 ,_或 $ 组成
- 数字不可以开头。
- 不可以使用关键字和保留字,但能包含关键字和保留字。
- Java中严格区分大小写,长度无限制。
- 标识符不能包含空格。
2.2、标识符的命名规范
-
包名:多单词组成时所有字母都小写:xxxyyyzzz。
例如:java.lang、com.atguigu.bean -
类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
例如:HelloWorld,String,System等 -
变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
例如:age,name,bookName,main,binarySearch,getName -
常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
例如:MAX_VALUE,PI,DEFAULT_CAPACITY
注意:在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。
class IdentifierTest{
public static void main(String[] args){
int abc = 12;
int age = 16; //age:标识符
char gender = '男';
}
public static void main1(String[] args){
}
}
03. 变量(重点)
3.1、为什么需要变量
变量是程序中不可或缺的组成单位,最基本的存储单元。
3.2、初识变量
变量的概念:
- 内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化
- 变量的构成包含三个要素:数据类型、变量名、存储的值
- Java中变量声明的格式:数据类型 变量名 = 变量值
class VariableTest{
public static void main(String[] args){
//定义变量的方式1
char gender; //过程1:变量的声明
gender = '男'; //过程2:变量的赋值(或初始化)
gender = '女';
//定义变量的方式2:声明与初始化合并
int age = 10;
System.out.println("Hello World!");
System.out.println(age);
System.out.println("age = " + age);
}
}
3.3、 Java中变量的数据类型
Java中变量的数据类型分为两大类:
- 基本数据类型:包括 整数类型、浮点数类型、字符类型、布尔类型。
- 引用数据类型:包括数组、 类、接口、枚举、注解、记录。
3.4、变量的使用
04. 基本数据类型介绍
4.1 整数类型:byte、short、int、long
4.2 浮点类型:float、double
/*
测试整型和浮点型变量的使用
*/
class VariableTest1{
public static void main(String[] args){
//1、测试整型变量的使用
// byte(1字节 = 8bit) \ short(2字节 ) \ int(4字节) \ long(8字节)
byte b1 = 12;
byte b2 = 127;
// byte b3 = 128; //编译不通过,因为超出了byte的存储范围
short s1 = 1234;
int i1 = 123234123;
//①声明long类型变量时,需要提供后缀,后缀为‘l’或'L'
long l1 = 123123123L;
//②开发中,定义整型变量时,无特殊情况,通常声明为int类型
//2、测试浮点型变量的使用
// float \ double
double d1 = 12.3;
//①声明float类型变量时,需要提供后缀,后缀为‘f’或'F'
float f1 = 12.3f;
System.out.println("f1 = " + f1);
//②开发中,定义浮点型变量时,无特殊情况,通常声明为double类型,因为精度更高
//③ float 类型表数范围大于long类型的,但是精度不高
//测试浮点型变量的精度,
//浮点型变量的精度不高,需要精确数字计算或保留指定位数的精度,需要使用BigDecimal类。
//测试1:
System.out.println(0.1 + 0.2);
//测试2:
float ff1 = 123123123f;
float ff2 = ff1 + 1;
System.out.println(ff1);
System.out.println(ff2);
System.out.println(ff1 == ff2);
}
}
java 计算金额时,使用 BigDecimal类替换,可以实现任意精度的数据的运算
4.2.1 关于浮点型精度的说明
- 并不是所有的小数都能可以精确的用二进制浮点数表示。二进制浮点数不能精确的表示0.1、0.01、0.001这样10的负次幂。
- 浮点类型float、double的数据不适合在不容许舍入误差的金融计算领域。如果需要精确数字计算或保留指定位数的精度,需要使用BigDecimal类。
4.2.2 应用举例
案例1:定义圆周率并赋值为3.14,现有3个圆的半径分别为1.2、2.5、6,求它们的面积。
class FloatDoubleExer{
public static void main(String[] args){
//定义圆周率变量
double pi = 3.14;
//定义三个圆的半径
double radius1 = 1.2;
double radius2 = 2.5;
double radius3 = 6;
//计算面积
double area1 = pi * radius1 * radius1;
double area2 = pi * radius2 * radius2;
double area3 = pi * radius3 * radius3;
//输出
System.out.println("圆1的半径为: " + radius1 + ",面积为:" + area1);
System.out.println("圆2的半径为: " + radius2 + ",面积为:" + area2);
System.out.println("圆3的半径为: " + radius3 + ",面积为:" + area3);
}
}
**案例2:**小明要到美国旅游,可是那里的温度是以华氏度为单位记录的。 它需要一个程序将华氏温度(80度)转换为摄氏度,并以华氏度和摄氏度为单位分别显示该温度。
// ℃ = (℉ - 32) / 1.8
public class Exercise2 {
public static void main(String[] args) {
double hua = 80;
double she = (hua-32)/1.8;
System.out.println("华氏度" + hua+"℉转为摄氏度是" +she+"℃");
}
}
4.3、字符类型:char
char使用的是Unicode字符集,包含了世界范围的所有字符
class CharTest{
public static void main(String[] args){
//形式1:使用单引号(' ')括起来的单个字符。
char c1 = 'a';
char c2 = '中';
char c3 = '1';
char c4 = '%';
char c5 = 'Y';
//编译不通过
//char c6 = '';
//char c7 = 'ab';
//形式2:直接使用 Unicode值来表示字符型常量
char c8 = '\u0036';
System.out.println(c8);
//形式3:使用转义字符‘\’
char c9 = '\n'; // '\n'表示换行符
char c10 = '\t';
System.out.println("hello" + c9 + "world");
//形式4:使用具体字符对应的数值(比如ASCII码)
char c11 = 97;
System.out.println(c11); // a
char c12 = '1';
char c13 = 1; //两者不相等
}
}
4.4、布尔类型:boolean
boolean类型数据只有两个值:true、false
boolean 类型用来判断逻辑条件,一般用于流程控制语句中:
- if条件控制语句;
- while循环控制语句;
- for循环控制语句;
- do-while循环控制语句;
class BooleanTest{
public static void main(String[] args){
// 布尔类型:boolean
boolean bo1 = true;
boolean bo2 = false;
//boolean 类型用来判断逻辑条件,一般用于流程控制语句中:
boolean isMarried = true;
if(isMarried){
System.out.println("很遗憾,不能参加单身派对了");
}else{
System.out.println("可以多谈几个男朋友或女朋友");
}
//不谈boolean类型占用空间的大小,都是,真正在内存中分配的话,使用的是4个字节
}
}
05、基本数据类型变量间运算规则
1、在Java程序中,不同的基本数据类型(只有7种,不包含boolean类型)变量的值经常需要进行相互转换。
2、转换的方式有两种:
自动类型提升
强制类型转换
5.1 自动类型提升
规则:将取值范围小(或容量小)的类型自动提升为取值范围大(或容量大)的类型
/*
取值范围小(或容量小)的类型自动提升为取值范围大(或容量大)的类型 。
特别的:
byte,short,char数据类型的变量进行算术运算时,结果按照int类型处理。
*/
class VariableTest3{
public static void main(String[] args){
int i1 = 10;
int i2 = 11;
long l1 = i1;
float f1 = l1;
byte b1 = 12;
int i3 = b1 + i1;
//编译不通过
//byte b2 = b1 + i1;
//特殊情况1:byte,short之间运算
byte b3 = 12;
short s1 = 10;
//编译不通过
//short s2 = b3 + s1;
i3 = b3 + s1;
byte b4 = 10;
int i4 = b3 + b4;
//特殊情况2:char
char c1 = 'a';
//编译不通过
//char c2 = c1 + b3;
int i5 = c1 + b3;
//**************************************
//练习1
long l2 = 123L;
long l3 = 123; //理解为:自动类型提升
//long l4 = 123123123123; //123123123123理解为int类型,因为超出了int范围,所以报错
long l5 = 123123123123L; //此时的123123123123L就是使用8个字节存储的long类型的值
//练习2
float f2 = 12.3F;
//float f3 = 12.3; //不满足自动类型提升的规则(double --> float ),所以报错
//练习3
//规定1:整型常量,规定是int类型
byte b5 = 10;
//byte b6 = b5 + 1;
int i11 = b5 + 1;
//规定2:浮点型常量,规定是double类型
double d2 = b5 + 12.3;
//练习4:为什么不允许变量名是数字开头。为了"自洽"
/*
int 123L = 12;
long l6 = 123L;
*/
}
}
5.2 强制类型转换
规则:将取值范围大(或容量大)的类型强制转换成取值范围小(或容量小)的类型。
转换格式:
数据类型1 变量名 = (数据类型1)被强转数据值; //()中的数据类型必须<=变量值的数据类型
当把存储范围大的值(常量值、变量的值、表达式计算的结果值)强制转换为存储范围小的变量时,可能会损失精度或溢出。
class VariableTest4{
public static void main(String[] args){
double d1 = 12; //自动类型提升
//编译不通过
//int i1 = d1;
int i2 = (int)d1;
System.out.println(i2);
long l1 = 123;
//编译不通过
//short s1 = l1;
short s2 = (short)l1;
System.out.println(s2);
//练习
int i3 = 12;
float f1 = i3; //自动类型提升
System.out.println(f1); // 12.0
float f2 = (float)i3; //编译可以通过,省略()而已
//精度损失的例子1
double d2 = 12.9;
int i4 = (int)d2;
System.out.println(i4);
//精度损失的例子2
int i5 = 128;
byte b1 = (byte)i5;
System.out.println(b1); //-128
//实际开发举例
byte b2 = 12;
method(b2);
long l2 = 12L;
//编译不通过
//method(l2);
method((int)l2);
}
public static void method(int num){ //int num = b2; 自动类型提升
System.out.println("num = " + num);
}
}
5.3 基本数据类型与String的运算
5.3.1 字符串类型:String
String不是基本数据类型,属于引用数据类型
使用一对""来表示一个字符串,内部可以包含0个、1个或多个字符。
声明方式与基本数据类型类似。例如:String str = “尚硅谷”;
class StringTest{
public static void main(String[] args){
String str1 = "Hello World!";
System.out.println("str1");
System.out.println(str1);
String str2 = "";
String str3 = "a";
}
}
5.3.2 运算规则
/*
测试强制类型转换
*/
class StringTest{
public static void main(String[] args){
String str1 = "Hello World!";
System.out.println("str1");
System.out.println(str1);
String str2 = "";
String str3 = "a";
//测试连接运算
int num1 = 10;
boolean b1 = true;
String str4 = "hello";
System.out.println(str4 + b1); //hellotrue
String str5 = str4 + b1;
String str6 = str4 + b1 + num1;
System.out.println(str6); //hellotrue10
//如何将String 类型转换为基本数据类型
String str7 = "abc"; //不能考虑转换为基本数据类型
int num2 = 10;
String str8 = num2 + ""; "10"
//编译不通过
//int num3 = (int)str8;
//使用Integer类
int num3 = Integer.parseInt(str8);
System.out.println(str8);
}
}
5.3.3 案例与练习
案例:公安局身份登记
要求填写自己的姓名、年龄、性别、体重、婚姻状况(已婚用true表示,单身用false表示)、联系方式等等。
class StringExer{
public static void main(String[] args){
String name = "莉莉";
int age = 18;
char gender = '女';
double weight = 99.1;
boolean isMarried = false;
String phoneNumber = "1234567890";
System.out.println("姓名: " + name + ",年龄:" + age + ",性别: " + gender + ",体重: " + weight + ",婚姻状况:" + isMarried + ",联系方式: " + phoneNumber);
}
}
06、进制的认识
- 二进制(binary)(以0B、0b开头)、十进制、八进制(以0开头)、十六进制(以0x、0X开头)的声明方式
- 二进制的理解
- 正数:原码、反码、补码三码合一
- 负数:原码、反码、补码不相同。
- 计算机的底层是以补码的方式存储数据的
- 熟悉:二进制与十进制之间的转换
- 了解:二进制与八进制、十六进制之间的转换
07、运算符(Operator)(重点)
7.1 算术运算符
7.1.1 基本语法
++ 或 – 不会改变数据类型
class AriTest {
public static void main(String[] args){
//-------------------------------------------------------------------------------
// 除法:/
int m1 = 12;
int n1 = 5;
int k1 = m1 / n1;
System.out.println(k1); //2
System.out.println(m1 / n1 * n1); //10
//取模(或取余) : %
int i1 = 12;
int j1 = 5;
System.out.println(i1 % j1); //2
//开发中,经常用来判断某个数num1能整除另外一个数num2。 num1 % num2 == 0
//比如判断num1是否是偶数: num1 % num2 == 0
//取模后,结果与被模数符号相同
int i2 = -12;
int j2 = 5;
System.out.println(i2 % j2); //-2
int i3 = 12;
int j3 = -5;
System.out.println(i3 % j3); //2
int i4 = -12;
int j4 = -5;
System.out.println(i4 % j4); //-2
//-------------------------------------------------------------------------------
//(前)++:先自增1,再运算
//(后)++:先运算,再自增1
int a1 = 10;
int b1 = ++a1;
System.out.println("a1 = " + a1 + ", b1 = " + b1); // a1 = 11,b1 = 11
int a2 = 10;
int b2 = a2++;
System.out.println("a2 = " + a2 + ", b2 = " + b2); // a2 = 11,b2 = 10
//练习1
int i = 10;
// i++;
++i;
System.out.println("i = " + i); // 11
//练习2
short s1 = 10;
//方式1
/*
//编译不通过
//s1 = s1 + 1;
s1 = (short)(s1 + 1);
System.out.println(s1);
*/
//方式2
s1++;
System.out.println(s1);
//-------------------------------------------------------------------------------
//(前)--:先自减1,再运算
//(后)--:先运算,再自减1
//+:连接符,只适用于String与其他类型的变量间的运算,而且运算结果也是String类型
}
}
7.1.2 案例与练习
案例1:
随意给出一个整数,打印显示它的个位数,十位数,百位数的值。
格式如下:
数字xxx的情况如下:
个位数:
十位数:
百位数:
例如:
数字153的情况如下:
个位数:3
十位数:5
百位数:1
class AriExer {
public static void main(String[] args){
int num = 153;
int ge = num % 10; // 个位
int shi = num / 10 % 10; //十位
int bai = num / 100; //百位
System.out.println("个位是: " + ge);
System.out.println("十位是: " + shi);
System.out.println("百位是: " + bai);
}
}
案例2:
为抵抗洪水,战士连续作战89小时,编程计算共多少天零多少小时?
class AriExer1 {
public static void main(String[] args){
int num = 89;
int day = num / 24;
int hour = num % 24;
System.out.println("共奋战: " + day + "天零" + hour + "小时");
}
}
额外案例1
System.out.println("5 + 5= " + 5 + 5); // 5 + 5= 55
System.out.println("5 + 5= " + (5 + 5)); // 5 + 5= 10
** 额外案例2**
byte bb1 = 127;
bb1++;
System.out.println("bb1 = " + bb1);//-128
** 额外案例3**
int i = 1;
int j = i++ + ++i * i++;
System.out.println("j = " + j); //10
** 额外案例4**
int i = 2;
int j = i++;
System.out.println(j); //2
int k = 2;
int z = ++k;
System.out.println(z); //3
int m = 2;
m = m++;
System.out.println(m); //2
7.2 赋值运算符
7.2.1 基本语法
= 、+=、 -=、*=、 /=、%=
/*
当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。
*/
class SetValueTest {
public static void main(String[] args){
int i = 5;
long l = 10; // 自动类型提升
byte b = (byte)i; //强制类型转换
//操作方式1
int a1 = 10;
int b1 = 10;
//操作方式2:连续赋值
int a2;
int b2;
//或合并:int a2,b2;
a2 = b2 = 10;
System.out.println(a2 + "," + b2);
//操作方式3:
//int a1 = 20;
//int b1 = 20;
int a2 = b2 = 20;
System.out.println(a3 + "," + b3);
//-------------------------------------------------------------------------------
// += 的使用
int m1 = 10;
m1 += 5;
// 类似于 m1 = m1 + 5;
System.out.println(m1);
byte by1 = 10;
by1 += 5; //by1 = by1 + 5; 会编译报错,改为 by1 = (byte)(by1 + 5);
System.out.println(by1);
int m2 = 1;
m2 *= 0.1; //m2 = (int)(m2 * 0.1)
System.out.println(m2);
//练习1:如何实现一个变量的值增加2
//方式1
int n1 = 10;
n1 = n1 + 2;
//方式2(推荐)
int n2 = 10;
n2 += 2;
//练习2:如何实现一个变量的值增加1
//方式1
int i1 = 10;
i1 = i1 + 1;
//方式2
int i2 = 10;
i2 += 1;
//方式3:(推荐)
int i3 = 10;
i3++; // ++i3;
}
}
7.3 比较(关系)运算符
•比较运算符的结果都是boolean型,也就是要么是true,要么是false。
•> < >= <= :只适用于基本数据类型(除boolean类型之外)
== != :适用于基本数据类型和引用数据类型
•比较运算符“==”不能误写成“=”
class CompareTest {
public static void main(String[] args) {
int i1 = 10;
int i2 = 20;
System.out.println(i1 == i2);//false
System.out.println(i1 != i2);//true
System.out.println(i1 >= i2);//false
int m = 10;
int n = 20;
System.out.println(m == n);//false
System.out.println(m = n);//20
boolean b1 = false;
boolean b2 = true;
System.out.println(b1 == b2);//false
System.out.println(b1 = b2);//true
}
}
7.4 逻辑运算符
逻辑运算符,操作的都是boolean类型的变量或常量,而且运算得结果也是boolean类型的值
public class LogicTest {
public static void main(String[] args) {
/*
区分:& 和 &&
–相同点:两个符号表达的都是且的关系,如果符号左边是true,则二者都执行符号右边的操作
–不同点:& : 如果符号左边是false,则继续执行符号右边的操作
&& :如果符号左边是false,则不再继续执行符号右边的操作
–建议:开发中,推荐使用 &&
*/
boolean b1 = true;
b1 = false;
int num1 = 10;
if(b1 & (num1++ >0)){
System.out.println("床前明月光");
}else{
System.out.println("我叫郭德纲");
}
System.out.println("num1 = " + num1);
boolean b2 = true;
b2 = false;
int num2 = 10;
if(b2 && (num2++ >0)){
System.out.println("床前明月光");
}else{
System.out.println("我叫郭德纲");
}
System.out.println("num2 = " + num2);
}
}
区分“|”和“||”:
— 相同点:如果符号左边是false,则二者都执行符号右边的操作
— 不同点:| : 如果符号左边是true,则继续执行符号右边的操作
|| :如果符号左边是true,则不再继续执行符号右边的操作
建议:开发中,推荐使用 ||
/*
1. 定义类 LogicExer
2. 定义 main方法
3. 定义一个int类型变量a,变量b,都赋值为20
4. 定义boolean类型变量bo1 , 判断++a 是否被3整除,并且a++ 是否被7整除,将结果赋值给bo1
5. 输出a的值,bo1的值
6. 定义boolean类型变量bo2 , 判断b++ 是否被3整除,并且++b 是否被7整除,将结果赋值给bo2
7. 输出b的值,bo2的值
*/
public class LogicExer {
public static void main(String[] args) {
int a,b;
a = b = 20;
boolean bo1 = (++a % 3 == 0) && (a++ % 7 == 0);
System.out.println("a = " + a + ",bo1 = " + bo1);
boolean bo2 = (b++ % 3 == 0) && (++b % 7 == 0);
System.out.println("b = " + b + ",bo2 = " + bo2);
}
}
7.5 位运算符
/*
位运算符
1、 << >> >>> & \ ^ ~
2、说明
①<< >> >>> & \ ^ ~ 针对数值类型的变量或常量进行运算,运算结果也是数值
②<< 每向左移动一位,相当于原数据*2。(正数、负数都适用)
>> 每向右移动一位,相当于原数据/2。 【注意】如果不能整除,向下取整。
>>> 往右移动后,左边空出来的位直接补0。(正数、负数都适用)
& 对应位都是1才为1,否则为0。
*/
class BitTest{
public static void main(String[] args) {
int num1 = 7;
System.out.println("num1 << 1 : " + (num1 << 1)); //num1 << 1 : 14
System.out.println("num1 << 2 : " + (num1 << 2)); // num1 << 2 : 28
System.out.println("num1 << 3 : " + (num1 << 3)); // num1 << 3 : 56
System.out.println("num1 << 28 : " + (num1 << 28)); //num1 << 28 : 1879048192
System.out.println("num1 << 29 : " + (num1 << 29)); //num1 << 29 : -536870912 过犹不及
int num2 = -7;
System.out.println("num2 << 1 : " + (num2 << 1)); //num2 << 1 : -14
System.out.println("num2 << 2 : " + (num2 << 2)); // num2 << 2 : -28
System.out.println("num2 << 3 : " + (num2 << 3)); // num2 << 3 : -56
//面试题:高效计算 2 * 8
// 2 << 3 或 8 << 1
//69>>4 类似于 69/2的4次 = 69/16 =4
System.out.println(69 >> 4); //4
System.out.println(62 >>> 3); //7
System.out.println(5 & 3);
}
}
//如何交换两个int型变量的值?String呢?
class BitExer {
public static void main(String[] args) {
int m = 10;
int n = 5;
System.out.println("m = " + m + ", n = " + n);
//(推荐)实现方式1:优点:容易理解,适用于不同数据类型 缺点:需要额外定义变量
//int temp = m;
//m = n;
//n = temp;
//实现方式2:优点:没有额外定义变量 缺点:可能超出int的范围;只能适用于数值类型
//m = m + n; //15 = 10 + 5
//n = m - n;//10 = 15 - 5
//m = m - n;//5 = 15 - 10
//实现方式3:优点:没有额外定义变量 缺点:不易理解;只能适用于数值类型
m = m ^ n;
n = m ^ n; //(m ^ n) ^ n
m = m ^ n;
System.out.println("m = " + m + ", n = " + n);
}
}
7.6 条件运算符
7.6.1 基本语法
条件运算符格式:
(条件表达式)? 表达式1:表达式2
说明:条件表达式是boolean类型的结果,根据boolean的值选择表达式1或表达式2
要求表达式1和表达式2为同种或兼容的类型
7.6.2 案例
class ConditionTest{
public static void main(String[] args) {
String info = (2 > 10)? "表达式1" : "表达式2";
System.out.println(info);
double result = (2 > 1)? 1 : 2.0;
System.out.println(result);
//练习1:获取两个数中的较大值
int m = 10;
int n = 20;
int max = (m > n)? m : n;
System.out.println("较大值为:" + max);
//练习2:获取三个数中的较大值
int i = 20;
int j = 30;
int k = 50;
int temp = (i > j)? i : j;
int finalMax = (temp > k)? temp : k;
System.out.println("较大值为:" + finalMax);
int finalMax1 = (((i > j)? i : j) > k)? ((i > j)? i : j) : k;
System.out.println("较大值为:" + finalMax1);
}
}
/*
练习:今天是周2,10天以后是周几?
*/
class ConditionExer{
public static void main(String[] args) {
int week = 2;
week += 10;
week %= 7;
System.out.println("今天是周2,10天以后是周" + ((week == 0)? "日" : week) );
}
}
7.6.3 与if-else的转换关系
凡是可以使用条件运算符的地方,都可以改写为if-else结构。反之,不成立
开发中,如果既可以使用条件运算符,又可以使用if-else,推荐使用条件运算符。因为执行效率稍高
7.7 运算符优先级
运算符有不同的优先级,所谓优先级就是在表达式运算中的运算符顺序。
上一行中的运算符总是优先于下一行的。
优先级 | 运算符说明 | Java运算符 |
---|---|---|
1 | 括号 | ()、[]、{} |
2 | 正负号 | +、- |
3 | 单元运算符 | ++、–、~、! |
4 | 乘法、除法、求余 | *、/、% |
5 | 加法、减法 | +、- |
6 | 移位运算符 | <<、>>、>>> |
7 | 关系运算符 | <、<=、>=、>、instanceof |
8 | 等价运算符 | ==、!= |
9 | 按位与 | & |
10 | 按位异或 | ^ |
11 | 按位或 | ” |
12 | 条件与 | && |
13 | 条件或 | ” |
14 | 三元运算符 | ? : |
15 | 赋值运算符 | =、+=、-=、*=、/=、%= |
16 | 位赋值运算符 | &=、 |
开发建议:
1.不要过多的依赖运算的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用()来控制表达式的执行顺序。
2.不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把它分成几步来完成。例如: (num1 + num2) * 2 > num3 && num2 > num3 ? num3 : num1 + num2;
三、流程控制语句
01、顺序结构
程序从上到下逐行地执行,中间没有任何判断和跳转
package testOne;
public class StatementTest {
public static void main(String[] args) {
int x = 1;
int y = 2;
System.out.println("x = " + x);
System.out.println("y = " + y);
//对x、y的值进行修改
x++;
y = 2 * x + y;
x = x * 10;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
}
02、分支语句
- 根据条件,选择性地执行某段代码。
- 有if…else和switch-case两种分支语句
2.1 if-else条件判断结构
2.1.1 基本语法
结构1:单分支条件判断:if
格式:
if(条件表达式){
语句块;
}
说明:条件表达式必须是布尔表达式(关系表达式或逻辑表达式)或 布尔变量。
结构2:双分支条件判断:if…else
格式:
if(条件表达式) {
语句块1;
}else {
语句块2;
}
结构3:多分支条件判断:if…else if…else
格式:
if (条件表达式1) {
语句块1;
} else if (条件表达式2) {
语句块2;
}
...
}else if (条件表达式n) {
语句块n;
} else {
语句块n+1;
}
说明:一旦条件表达式为true,则进入执行相应的语句块。执行完对应的语句块之后,就跳出当前结构
当条件表达式之间是“互斥”关系时(即彼此没有交集),条件判断语句及执行语句间顺序无所谓。
当条件表达式之间是“包含”关系时,“小上大下 / 子上父下”,否则范围小的条件表达式将不可能被执行。
2.1.2 应用举例
案例1:成年人心率的正常范围是每分钟60-100次。体检时,如果心率不在此范围内,则提示需要做进一步的检查。
public class IfElseTest1 {
public static void main(String[] args){
int heartBeats = 89;
if(heartBeats < 60 || heartBeats > 100){
System.out.println("你需要做进一步的检查");
}
System.out.println("体检结束");
}
}
案例2:定义一个整数,判定是偶数还是奇数
public class IfElseTest2 {
public static void main(String[] args){
int a = 10;
if(a % 2 == 0) {
System.out.println(a + "是偶数");
} else{
System.out.println(a + "是奇数");
}
}
}
案例3:
岳小鹏参加Java考试,他和父亲岳不群达成承诺:
如果:
成绩为100分时,奖励一辆跑车;
成绩为(80,99]时,奖励一辆山地自行车;
当成绩为[60,80]时,奖励环球影城一日游;
其它时,胖揍一顿。
说明:默认成绩是在[0,100]范围内
public class IfElseTest3 {
public static void main(String[] args) {
int score = 67;//岳小鹏的期末成绩
//写法一:默认成绩范围为[0,100]
if(score == 100){
System.out.println("奖励一辆跑车");
}else if(score > 80 && score <= 99){ //错误的写法:}else if(80 < score <= 99){
System.out.println("奖励一辆山地自行车");
}else if(score >= 60 && score <= 80){
System.out.println("奖励环球影城玩一日游");
}
//else{
// System.out.println("胖揍一顿");
//}
//写法二:
// 默认成绩范围为[0,100]
if(score == 100){
System.out.println("奖励一辆跑车");
}else if(score > 80){
System.out.println("奖励一辆山地自行车");
}else if(score >= 60){
System.out.println("奖励环球影城玩一日游");
}else{
System.out.println("胖揍一顿");
}
}
}
2.1.3 if…else嵌套
在 if 的语句块中,或者是在else语句块中,又包含了另外一个条件判断(可以是单分支、双分支、多分支),就构成了嵌套结构。
执行的特点:
(1)如果是嵌套在if语句块中的,只有当外部的if条件满足,才会去判断内部的条件
(2)如果是嵌套在else语句块中的,只有当外部的if条件不满足,进入else后,才会去判断内部的条件
案例4:由键盘输入三个整数分别存入变量num1、num2、num3,对它们进行排序(使用 if-else if-else),并且从小到大输出。
import java.util.Scanner;
public class StatementTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("输入第1个整数: " );
int num1 = in.nextInt();
System.out.println("输入第2个整数: " );
int num2 = in.nextInt();
System.out.println("输入第3个整数: ");
int num3 = in.nextInt();
if(num1 >= num2){
if (num3 >= num1){
System.out.println(num2 + "," + num1 + "," + num3);
}else if(num3 <= num2){
System.out.println(num3 + "," + num2 + "," + num1);
}else {
System.out.println(num2 + ',' + num3 + ',' + num1);
}
}else {
if (num3 >= num2){
System.out.println(num2 + "," + num3 + "," + num1);
}else if(num3 <= num1){
System.out.println(num3 + "," + num1 + "," + num2);
}else {
System.out.println(num1 + ',' + num3 + ',' + num2);
}
}
}
}
2.1.4 练习
练习1:
对下列代码,若有输出,指出输出结果
int x = 4;
int y = 1;
if (x > 2) {
if (y > 2)
System.out.println(x + y);
System.out.println("atguigu");
} else
System.out.println("x is " + x);
练习2:
boolean b = true;
//如果写成if(b=false)能编译通过吗?如果能,结果是?
if(b == false) //建议:if(!b)
System.out.println("a");
else if(b)
System.out.println("b");
else if(!b)
System.out.println("c");
else
System.out.println("d");
练习3:
定义两个整数,分别为small 和 big,如果第一个整数small大于第二个整数big,就交换。输出显示small和big变量的值。
public static void main(String[] args) {
int small = 10;
int big = 30;
if(small > big){
int tmp = small;
small = big;
big = tmp;
}
System.out.println(small + " 、 "+ big);
}
练习4:
小明参加期末Java考试,通过考试成绩,判断其Java等级,成绩范围[0,100]
- 90-100 优秀
- 80-89 好
- 70-79 良
- 60-69 及格
- 60以下 不及格
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("小明的期末Java成绩是: ");
int score = scan.nextInt();
if (score < 0 || score > 100) {
System.out.println("你的成绩是错误的");
}else if(score >= 90){
System.out.println("你的成绩属于优秀");
}else if (score >= 80) {
System.out.println("你的成绩属于好");
} else if (score >= 70) {
System.out.println("你的成绩属于良");
} else if (score >= 60) {
System.out.println("你的成绩属于及格");
} else {
System.out.println("你的成绩属于不及格");
}
}
练习5:
编写程序,声明2个int型变量并赋值。判断两数之和,如果大于等于50,打印“hello world!”
public static void main(String[] args) {
int a = 20;
int b = 90;
if(a + b >= 50){
System.out.println("hello world!");
}
}
练习6:
编写程序,声明2个double型变量并赋值。判断第一个数大于10.0,且第2个数小于20.0,打印两数之和。否则,打印两数的乘积。
public static void main(String[] args) {
double num1 = 21.0;
double num2 = 19.0;
if (num1 > 10.0 && num2 < 20.0){
System.out.println(num1 + num2);
}else {
System.out.println(num1 * num2);
}
}
练习7:判断水的温度
如果大于95℃,则打印“开水”;
如果大于70℃且小于等于95℃,则打印“热水”;
如果大于40℃且小于等于70℃,则打印“温水”;
如果小于等于40℃,则打印“凉水”。
public static void main(String[] args) {
int waterTemperature = 62;
if (waterTemperature > 95){
System.out.println("开水");
}else if (waterTemperature >70){
System.out.println("热水");
}else if (waterTemperature > 40){
System.out.println("温水");
}else {
System.out.println("凉水");
}
}
2.2 switch-case 选择结构
2.2.1 基本语法
语法格式
switch(表达式){
case 常量值1:
执行语句1;
//break;
case 常量值2:
执行语句2;
//break;
// ...
[default:
执行语句n+1;
break;
]
}
执行流程图
执行过程
- 第1步:根据switch中表达式的值,依次匹配各个case。如果表达式的值等于某个case中的常量值,则执行对应case中的执行语句。
- 第2步:执行完此case的执行语句以后,
- 情况1:如果遇到break,则执行break并跳出当前的switch-case结构
- 情况2:如果没有遇到break,则会继续执行当前case之后的其它case中的执行语句。—>case穿透 … 直到遇到break关键字或执行完所有的case及default的执行语句,跳出当前的switch-case结构
public class SwitchCaseTest {
public static void main(String[] args) {
int num = 1;
switch (num){
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("one");
break;
case 2:
System.out.println("two");
break;
case 3:
System.out.println("three");
break;
default:
System.out.println("other");
break;
}
}
}
public class SwitchCaseTest2 {
public static void main(String args[]) {
String season = "summer";
switch (season) {
case "spring":
System.out.println("春暖花开");
break;
case "summer":
System.out.println("夏日炎炎");
break;
case "autumn":
System.out.println("秋高气爽");
break;
case "winter":
System.out.println("冬雪皑皑");
break;
default:
System.out.println("季节输入有误");
break;
}
}
}
使用注意点:
- switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0);
- case子句中的值必须是常量,不能是变量名或不确定的表达式值或范围;
- 同一个switch语句,所有case子句中的常量值互不相同;
- break语句用来在执行完一个case分支后使程序跳出switch语句块;
- 如果没有break,程序会顺序执行到switch结尾;
- default子句是可选的。同时,位置也是灵活的。当没有匹配的case时,执行default语句。
2.2.2 if-else语句与switch-case语句比较
- 结论:凡是使用switch-case的结构都可以转换为if-else结构。反之,不成立。
- 开发经验:如果既可以使用switch-case,又可以使用if-else,建议使用switch-case。因为效率稍高。
- 细节对比:
- if-else语句优势
- if语句的条件是一个布尔类型值,if条件表达式为true则进入分支,可以用于范围的判断,也可以用于等值的判断,使用范围更广。
- switch语句的条件是一个常量值(byte,short,int,char,枚举,String),只能判断某个变量或表达式的结果是否等于某个常量值,使用场景较狭窄。
- switch语句优势
- 当条件是判断某个变量或表达式是否等于某个固定的常量值时,使用if和switch都可以,习惯上使用switch更多。因为效率稍高。当条件是区间范围的判断时,只能使用if语句。
- 使用switch可以利用穿透性,同时执行多个分支,而if…else没有穿透性。
- if-else语句优势
2.2.3 案例
案例1
使用switch-case实现:对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。
public class SwitchCaseTest {
public static void main(String[] args) {
int score = 99;
switch (score/60){
case 0:
System.out.println("不及格");
break;
case 1:
System.out.println("及格");
break;
default:
System.out.println("输入的成绩有误");
break;
}
}
}
switch(score / 10){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("不及格");
break;
case 6:
case 7:
case 8:
case 9:
case 10:
System.out.println("及格");
break;
default:
System.out.println("输入的成绩有误");
break;
}
案例2
编写程序:从键盘上输入2023年的“month”和“day”,要求通过程序输出输入的日期为2023年的第几天。
import java.util.Scanner;
public class SwitchCaseTest {
public static void main(String[] args) {
//1、使用scanner,从键盘获取2023年的month、day
Scanner scan = new Scanner(System.in); //阻塞式方法
System.out.println("请输入2023年的月份");
int month = scan.nextInt();
System.out.println("请输入2023年的天:");
int day = scan.nextInt();
//2、使用switch-case 实现分支结构
int sumDay = 0; //记录总天数
//方式1,不推荐,冗余
/* switch (month){
case 1:
sumDay = day;
break;
case 2:
sumDay = 31 + day;
break;
case 3:
sumDay = 31 + 28 + day;
break;
case 4:
sumDay = 31 + 28 + 31 + day;
break;
case 5:
sumDay = 31 + 28 + 31 + 30 + day;
break;
case 6:
sumDay = 31 + 28 + 31 + 30 + 31 + day;
break;
case 7:
sumDay = 31 + 28 + 31 + 30 + 31 +30 + day;
break;
case 8:
sumDay = 31 + 28 + 31 + 30 + 31 +30 + 31 + day;
break;
case 9:
sumDay = 31 + 28 + 31 + 30 + 31 +30 + 31 + 31 + day;
break;
case 10:
sumDay = 31 + 28 + 31 + 30 + 31 +30 + 31 + 31 + 30 + day;
break;
case 11:
sumDay = 31 + 28 + 31 + 30 + 31 +30 + 31 + 31 + 30 + 31 + day;
break;
case 12:
sumDay = 31 + 28 + 31 + 30 + 31 +30 + 31 + 31 + 30 + 31 + 30 + day;
break;
}*/
//方式2
switch (month){
case 12:
sumDay += 30;
case 11:
sumDay += 31;
case 10:
sumDay += 30;
case 9:
sumDay += 31;
case 8:
sumDay += 31;
case 7:
sumDay += 30;
case 6:
sumDay += 31;
case 5:
sumDay += 30;
case 4:
sumDay += 31;
case 3:
sumDay += 28;
case 2:
sumDay += 31;
case 1:
sumDay += day;
break;
}
System.out.println("2023年" + month + "月" + day + "日,是当前的第" + sumDay + "天");
scan.close(); //为了防止内存泄漏
}
}
/*
import java.util.regex.Pattern;
import java.util.regex.Matcher;
//使用正则表达式进行日期校验
public class DateValidator {
private static final String DATE_PATTERN = "^(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])-(19|20)\\d\\d$";
public static boolean isValidDate(String date) {
Pattern pattern = Pattern.compile(DATE_PATTERN);
Matcher matcher = pattern.matcher(date);
return matcher.matches();
}
public static void main(String[] args) {
String date = "2023-06-23";
boolean isValid = isValidDate(date);
System.out.println(" isValid: " + isValid);
}
} */
2.2.4 练习
练习1
从键盘输入星期的整数值,输出星期的英文单词
import java.util.Scanner;
public class SwitchCaseExer1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入星期值:");
int weekday = input.nextInt();
switch (weekday){
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
default:
System.out.println("你输入的星期值有误!");
break;
}
input.close();
}
}
练习2
使用 switch 把小写类型的 char型转为大写。只转换 a, b, c, d, e. 其它的输出 “other”。
public class SwitchCaseExer2 {
public static void main(String[] args) {
char word = 'c';
switch (word){
case 'a':
System.out.println('A');
break;
case 'b':
System.out.println('B');
break;
case 'c':
System.out.println('C');
break;
case 'd':
System.out.println('D');
break;
case 'e':
System.out.println('E');
break;
default:
System.out.println("other");
}
}
}
练习3
编写程序:从键盘上读入一个学生成绩,存放在变量score中,根据score的值输出其对应的成绩等级:
score>=90 等级: A
70<=score<90 等级: B
60<=score<70 等级: C
score<60 等级: D
方式一:使用if-else
方式二:使用switch-case: score / 10: 0 - 10
import java.util.Scanner;
public class SwitchCaseExer3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入学生成绩:");
int score = input.nextInt();
char grade;//记录学生等级
/* if (score >= 90){
grade = 'A';
}else if (score >= 70){
grade = 'B';
}else if (score >= 60){
grade = 'C';
}else {
grade = 'D';
}*/
//方式2:
switch(score / 10){
case 10:
case 9:
grade = 'A';
break;
case 8:
case 7:
grade = 'B';
break;
case 6:
grade = 'C';
break;
default :
grade = 'D';
}
System.out.println("学生成绩为" + score + ",对应的等级为" + grade);
input.close();
}
}
练习4
编写一个程序,为一个给定的年份找出其对应的中国生肖。中国的生肖基于12年一个周期,每年用一个动物代表:rat、ox、tiger、rabbit、dragon、snake、horse、sheep、monkey、rooster、dog、pig。
提示:2022年:虎 2022 % 12 == 6
import java.util.Scanner;
/**
* @author davina
* @create 18:20
*/
public class SwitchCaseExer4 {
public static void main(String[] args) {
//从键盘输入一个年份
Scanner input = new Scanner(System.in);
System.out.println("请输入年份:");
int year = input.nextInt();
input.close();
//判断
switch (year % 12) {
case 0:
System.out.println(year + "是猴年");
break;
case 1:
System.out.println(year + "是鸡年");
break;
case 2:
System.out.println(year + "是狗年");
break;
case 3:
System.out.println(year + "是猪年");
break;
case 4:
System.out.println(year + "是鼠年");
break;
case 5:
System.out.println(year + "是牛年");
break;
case 6:
System.out.println(year + "是虎年");
break;
case 7:
System.out.println(year + "是兔年");
break;
case 8:
System.out.println(year + "是龙年");
break;
case 9:
System.out.println(year + "是蛇年");
break;
case 10:
System.out.println(year + "是马年");
break;
case 11:
System.out.println(year + "是羊年");
break;
default:
System.out.println(year + "输入错误");
}
}
}
练习5:押宝游戏
随机产生3个1-6的整数,如果三个数相等,那么称为“豹子”,如果三个数之和大于9,称为“大”,如果三个数之和小于等于9,称为“小”,用户从键盘输入押的是“豹子”、“大”、“小”,并判断是否猜对了
提示:随机数 Math.random()产生 [0,1)范围内的小数
如何获取[a,b]范围内的随机整数呢?(int)(Math.random() * (b - a + 1)) + a
import java.util.Scanner;
public class SwitchCaseExer5 {
public static void main(String[] args) {
//1、随机产生3个1-6的整数
int a = (int)(Math.random()*6 + 1);
int b = (int)(Math.random()*6 + 1);
int c = (int)(Math.random()*6 + 1);
//2、押宝
Scanner input = new Scanner(System.in);
System.out.print("请押宝(豹子、大、小):");
String ya = input.next();
input.close();
//3、判断结果
boolean result = false;
//switch支持String类型
switch (ya){
case "豹子": result = a == b && b == c; break;
case "大": result = a + b + c > 9; break;
case "小": result = a + b + c <= 9; break;
default:System.out.println("输入有误!");
}
System.out.println("a,b,c分别是:" + a +"," + b +"," + c );
System.out.println(result ? "猜中了" : "猜错了");
}
}
03、循环语句
-
根据循环条件,重复性的执行某段代码。
-
有for、while、do-while
-
三种循环语句。
-
补充:JDK5.0 提供了foreach循环,方便的遍历集合、数组元素。
-
理解:循环语句具有在某些条件满足的情况下,反复执行特定代码的功能。
-
循环结构分类:
- for 循环
- while 循环
- do-while 循环
-
循环结构四要素:
- 初始化部分
- 循环条件部分
- 循环体部分
- 迭代部分
3.1 for循环
3.1.1 基本语法
语法格式:
for (①初始化部分; ②循环条件部分; ④迭代部分){
③循环体部分;
}
执行过程:①-②-③-④-②-③-④-②-③-④-…-②
3.1.2 应用举例
案例1:使用for循环重复执行某些语句
题目:输出5行HelloWorld
public class ForTest1 {
public static void main(String[] args) {
/* 需求1:控制台输出5行Hello World!
写法1:
System.out.println("Hello World!");
System.out.println("Hello World!");
System.out.println("Hello World!");
System.out.println("Hello World!");
System.out.println("Hello World!");*/
//写法2:
for(int i = 1;i <= 5;i++){
System.out.println("Hello World!");
}
}
}
public class ForTest2 {
public static void main(String[] args) {
int num = 1;
for(System.out.print("a");num < 3;System.out.print("c"),num++){
System.out.print("b");
}
}
}
案例2 累加
题目:遍历1-100以内的偶数,并获取偶数的个数,获取所有的偶数的和
public class ForTest3 {
public static void main(String[] args) {
int count = 0;//记录偶数的个数
int sum = 0;//记录偶数的和
for(int i = 1;i <= 100;i++){
if(i % 2 == 0){
System.out.println(i);
count++;
sum += i;
}
}
System.out.println("偶数的个数为:" + count);
System.out.println("偶数的总和为:" + sum);
}
}
案例3:结合分支结构使用
题目:输出所有的水仙花数,所谓水仙花数是指一个3位数,其各个位上数字立方和等于其本身。例如: 153 = 111 + 333 + 555
public class ForTest4 {
public static void main(String[] args) {
//定义统计变量,初始化值是0
int count = 0;
//获取三位数,用for循环实现
for(int x = 100; x < 1000; x++) {
//获取三位数的个位,十位,百位
int ge = x % 10;
int shi = x / 10 % 10;
int bai = x / 100;
//判断这个三位数是否是水仙花数,如果是,统计变量++
if((ge*ge*ge+shi*shi*shi+bai*bai*bai) == x) {
System.out.println("水仙花数:" + x);
count++;
}
}
//输出统计结果就可以了
System.out.println("水仙花数共有"+count+"个");
}
}
案例5: 结合break的使用
说明:输入两个正整数m和n,求其最大公约数和最小公倍数。
比如:12和20的最大公约数是4,最小公倍数是60。
import java.util.Scanner;
//输入两个正整数m和n,求其最大公约数和最小公倍数
public class ForTest1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入正整数m: ");
int m = input.nextInt();
System.out.println("请输入正整数n: ");
int n = input.nextInt();
//获取m和n中的较小值
int min = (m < n)? m : n;
//需求1:最大公约数
//方式1:
int result = 1;
for (int i = 1; i <= min; i++) {
if (m % i == 0 && n % i == 0){
//System.out.println(i);
result = i;
}
}
System.out.println(result);
//方式2:推荐
for (int i = min; i >= 1; i--) {
if (m % i == 0 && n % i == 0) {
System.out.println(i);
break; //一旦执行就跳出当前循环
}
}
//需求2:最小公倍数
int max = (m > n)? m : n;
for (int i = max; i <= m * n; i++) {
if (i % m == 0 && i % n == 0 ){
System.out.println(i);
break;
}
}
}
}
说明:
- 1、我们可以在循环中使用break。一旦执行break,就跳出当前循环结构。
- 2、小结:如何结束一个循环结构?
- 结束情况1:循环结构中的循环条件部分返回false
- 结束情况2:循环结构中执行了break。
- 3、如果一个循环结构不能结束,那就是一个死循环!我们开发中要避免出现死循环
3.2 while循环
3.2.1 基本语法
语法格式:
①初始化部分
while(②循环条件部分){
③循环体部分;
④迭代部分;
}
执行过程:①-②-③-④-②-③-④-②-③-④-…-②
图示:
说明:
- while(循环条件)中循环条件必须是boolean类型。
- 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
- for循环和while循环可以相互转换。二者没有性能上的差别。实际开发中,根据具体结构的情况,选择哪个格式更合适、美观。
- for循环与while循环的区别:初始化条件部分的作用域不同。
3.2.2 应用举例
需求1:遍历50次hello world
需求2:遍历1-100的偶数,并计算所有偶数的和、偶数的个数(累加的思想)
public class WhileTest {
public static void main(String[] args) {
//需求1:遍历50次hello world
int i = 1;
while (i <= 50){
System.out.println("hello world!!");
i++;
}
//需求2:遍历1-100的偶数,并计算所有偶数的和、偶数的个数(累加的思想)
int j = 1;
int count = 0;//记录偶数的个数
int sum = 0; //记录偶数的总和
while (j <= 100){
if (j % 2 == 0){
System.out.println(j);
count++;
sum += j;
}
j++;
}
System.out.println("偶数的个数为:" + count);
System.out.println("偶数的总和为:" + sum);
}
}
案例3:猜数字游戏
随机生成一个100以内的数,猜这个随机数是多少?
从键盘输入数,如果大了,提示大了;如果小了,提示小了;如果对了,就不再猜了,并统计一共猜了多少次。
提示:生成一个[a,b] 范围的随机数的方式:(int)(Math.random() * (b - a + 1) + a)
import java.util.Scanner;
public class WhileTest1 {
public static void main(String[] args) {
//1、生成一个[1,100]范围的随机整数
int random = (int) (Math.random() * 100) + 1;
//2、使用scanner,从键盘获取数据
Scanner scan = new Scanner(System.in);
System.out.println("请输入1-100范围内的一个整数:");
int guess = scan.nextInt();
//3、声明一个变量,记录猜的次数
int guessCount = 1;
//3、使用循环结构,进行多次循环的对比和获取数据
while (random != guess){
if (guess > random){
System.out.println("你输入的数据大了");
}else if (guess < random){
System.out.println("你输入的数据小了");
}
System.out.println("请输入1-100范围内的一个整数:");
guess = scan.nextInt();
guessCount++;
}
System.out.println("恭喜你!猜对了");
System.out.println("共猜了" + guessCount + "次");
}
}
案例4:折纸珠穆朗玛峰
世界最高山峰是珠穆朗玛峰,它的高度是8848.86米,假如我有一张足够大的纸,它的厚度是0.1毫米。
请问,我折叠多少次,可以折成珠穆朗玛峰的高度?
public class WhileTest2 {
public static void main(String[] args) {
//1、声明珠峰的高度,纸的默认厚度
double paper = 0.1; //单位:毫米
double zf = 8848860; //单位:毫米
//2、定义一个变量,记录折纸的次数
int count = 0;
//3、通过循环结构,不断调整纸的厚度(当纸的厚度超过珠峰高度时,停止循环)
while (paper <= zf){
paper *= 2;
count++;
}
System.out.println("paper的高度为:" + (paper / 1000) + ",超过了珠峰的高度" + (zf / 1000));
System.out.println("共折纸" + count + "次");
}
}
3.3 do-while循环
3.3.1 基本语法
语法格式:
①初始化部分;
do{
③循环体部分
④迭代部分
}while(②循环条件部分);
**执行过程:**①-③-④-②-③-④-②-③-④-…-②
图示:
说明:
- 结尾while(循环条件)中循环条件必须是boolean类型
- do{}while();最后有一个分号
- do-while结构的循环体语句是至少会执行一次,这个和for和while是不一样的
- 循环的三个结构for、while、do-while三者是可以相互转换的。
3.3.2 应用举例
案例1:
遍历1-100的偶数,并计算所有偶数的和、偶数的个数(累加的思想)
public class DoWhileTest {
public static void main(String[] args) {
//需求1:遍历1-100的偶数,并计算所有偶数的和、偶数的个数
int i = 1;
int count = 0; //记录偶数的个数
int sum = 0; //记录偶数的总和
do {
if (i % 2 == 0){
System.out.println(i);
count++;
sum += i;
}
i++;
}while (i <= 100);
System.out.println("偶数的个数为:" + count);
System.out.println("偶数的总和为:" + sum);
}
}
案例2:体会do-while至少会执行一次循环体
class DoWhileTest2 {
public static void main(String[] args) {
//while循环:
int num1 = 10;
while(num1 > 10){
System.out.println("hello:while");
num1--;
}
//do-while循环:
int num2 = 10;
do{
System.out.println("hello:do-while");
num2--;
}while(num2 > 10);
}
}
案例3:ATM取款
声明变量balance并初始化为0,用以表示银行账户的余额,下面通过ATM机程序实现存款,取款等功能。
=ATM
1、存款
2、取款
3、显示余额
4、退出
请选择(1-4):
import java.util.Scanner;
public class DoWhileTest1 {
public static void main(String[] args) {
//1、定义一个变量,记录银行账户余额
double balance = 0.0;
boolean flag = true; //控制循环的结束
Scanner input = new Scanner(System.in); //实例化scanner
do {
//2、声明ATM收款界面
System.out.println("=========ATM========");
System.out.println("1、存款" );
System.out.println("2、取款" );
System.out.println("3、显示余额" );
System.out.println("4、退出" );
System.out.println("请选择(1-4):");
//3、使用scanner获取用户的选择
int selection = input.nextInt();
switch (selection){
//4、根据用户的选择,决定执行存款、取款、显示余额、退出的操作
case 1:
System.out.println("请输入存款的金额:");
double money1 = input.nextDouble();
if (money1 > 0){
balance += money1;
}
break;
case 2:
System.out.println("请输入取款的金额:");
double money2 = input.nextDouble();
if (money2 > 0 && money2 <= balance){
balance -= money2;
}else {
System.out.println("输入的数据有误或余额不足");
}
break;
case 3:
System.out.println("显示金额为:" + balance);
break;
case 4:
flag = false;
System.out.println("感谢使用,欢迎下次光临");
break;
default:
System.out.println("输入有误,请重新输入");
}
}while (flag);
//关闭资源
input.close();
}
}
3.4 对比三种循环结构
三种循环结构都具有四个要素:
- 循环变量的初始化条件
- 循环条件
- 循环体语句块
- 循环变量的修改的迭代表达式
从循环次数角度分析
- do-while循环至少执行一次循环体语句。
- for和while循环先判断循环条件语句是否成立,然后决定是否执行循环体。
如何选择
- 遍历有明显的循环次数(范围)的需求,选择for循环
- 遍历没有明显的循环次数(范围)的需求,选择while循环
- 如果循环体语句块至少执行一次,可以考虑使用do-while循环
- 本质上:三种循环之间完全可以互相转换,都能实现循环的功能
3.5 "无限"循环
3.5.1 基本语法
语法格式:
- 最简单"无限"循环格式:while(true) , for(;😉
适用场景: - 开发中,有时并不确定需要循环多少次,需要根据循环体内部某些条件,来控制循环的结束(使用break)。
- 如果此循环结构不能终止,则构成了死循环!开发中要避免出现死循环。
3.5.2 应用举例
案例1:实现爱你到永远.
public class ForWhileTest {
public static void main(String[] args) {
/* while (true){
System.out.println("I love you");
}*/
for (;;){
System.out.println("I love you");
}
//死循环的后面不能有执行语句
//System.out.println("end");
}
}
案例2:
从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序。
import java.util.Scanner;
public class ForWhileTest1 {
public static void main(String[] args) {
//从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序。
int positiveCount = 0; //记录正数的个数
int negativeCount = 0; //记录负数的个数
Scanner input = new Scanner(System.in);
while (true){
System.out.println("请输入一个整数(输入为0时结束程序):");
int num = input.nextInt(); //获取用户输入的整数
if (num > 0){ //正数
positiveCount++;
}else if (num < 0){
negativeCount++;
}else {
System.out.println("程序结束");
break;
}
}
System.out.println("正数的个数为:" + positiveCount);
System.out.println("负数的个数为:" + negativeCount);
}
}
3.6 嵌套循环(或多重循环)
3.6.1 使用说明
所谓嵌套循环:是指一个循环结构A的循环体是另一个循环结构B。比如,for循环里面还有一个for循环,就是嵌套循环。其中,for ,while ,do-while均可以作为外层循环或内层循环。
- 外层循环:循环结构A
- 内层循环:循环结构B
实质上,嵌套循环就是把内层循环当成外层循环的循环体。只有当内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的外层循环。
设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。
技巧:从二维图形的角度看,外层循环控制行数,内层循环控制列数。
开发经验:实际开发中,我们最多见到的嵌套循环是两层。一般不会出现超过三层的嵌套循环。如果将要出现,一定要停下来重新梳理业务逻辑,重新思考算法的实现,控制在三层以内。否则,可读性会很差。
3.6.2 应用举例
案例1:打印5行6个*
*******
*******
*******
*******
*******
public class ForForTest {
public static void main(String[] args) {
for (int j = 1;j <= 5;j++){
for (int i = 0; i <= 6 ; i++) {
System.out.print("*");
}
System.out.println();
}
}
}
案例2:打印5行直角三角形
*
**
***
****
*****
public class ForForTest {
public static void main(String[] args) {
for (int j = 1;j <= 5;j++){
for (int i = 1; i <= j ; i++) {
System.out.print("*");
}
System.out.println();
}
}
}
**案例3:**打印6行倒直角三角形
******
*****
****
***
**
*
public class ForForTest {
public static void main(String[] args) {
for (int j = 1;j <= 6;j++){
for (int i = 1; i <= 7- j ; i++) {
System.out.print("*");
}
System.out.println();
}
}
}
案例4:打印"菱形"形状的图案
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
* * * * * * *
* * * * *
* * *
*
public class ForForTest {
public static void main(String[] args) {
//上半部分
for (int i = 1; i <= 5; i++) {
//空格
for (int j = 1; j <= 10 -2*i ; j++) {
System.out.print(" ");
}
//*
for (int k = 1; k <= 2 * i -1 ; k++) {
System.out.print("* ");
}
//换行
System.out.println();
}
//下半部分
for (int i = 1; i <= 4; i++) {
//空格
for (int j = 1; j <= 2 * i; j++) {
System.out.print(" ");
}
//*
for (int k = 1; k <= 9 - 2 * i; k++) {
System.out.print("* ");
}
System.out.println();
}
}
}
案例5:九九乘法表
public class NineNineTable {
public static void main(String[] args) {
for (int i = 1; i <= 9 ; i++) {
for (int j = 1; j <= i ; j++) {
System.out.print(i + "*" + j + "=" + (i * j) + "\t");
}
System.out.println();
}
}
}
3.6.3 练习
练习1:将一天中的时间打印到控制台
public class ForForTest1 {
public static void main (String[] args) {
for (int hour = 0;hour < 24 ;hour++ ) {
for (int min = 0; min < 60 ; min++) {
System.out.println(hour + "时" + min +"分");
}
}
}
}
04、关键字break和continue的使用
4.1 break和continue的说明
适用范围 | 在循环结构中使用的作用 | 相同点 |
---|---|---|
break switch-case 、循环结构 | 一旦执行,就结束(或跳出)当前循环结构 | 此关键字的后面,不能声明语句 |
continue 循环结构 | 一旦执行,就结束(或跳出)当次循环 | 此关键字的后面,不能声明语句 |
此外,很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条语句上,然后执行它,但使程序容易出错。Java中的break和continue是不同于goto的。
4.2 应用举例
public class NineNineTable {
public static void main(String[] args) {
for(int i = 1;i <= 10;i++){
if(i % 4 == 0){
//break;//123
continue;//123567910
}
System.out.print(i);
}
System.out.println("####");
//嵌套循环中的使用
for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 10;j++){
if(j % 4 == 0){
//break; //结束的是包裹break关键字的最近的一层循环!
continue;//结束的是包裹break关键字的最近的一层循环的当次!
}
System.out.print(j);
}
System.out.println();
}
}
}
4.3 带标签的使用
break语句用于终止某个语句块的执行
{ ……
break;
……
}
break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
label1: { ……
label2: { ……
label3: { ……
break label2;
……
}
}
}
- continue语句出现在多层嵌套的循环语句体中时,也可以通过标签指明要跳过的是哪一层循环。
- 标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面。
- 举例:
class BreakContinueTest2 {
public static void main(String[] args) {
l:for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 10;j++){
if(j % 4 == 0){
//break l;
continue l;
}
System.out.print(j);
}
System.out.println();
}
}
}
4.4 经典案例
题目:找出100以内所有的素数(质数)?100000以内的呢?
public class PrimeNumberTest {
public static void main(String[] args) {
//方式一
/* for (int i = 2; i <= 100 ; i++) { //遍历100以内自然数
int number = 0; //记录i的约数的个数(从2开始)
//判断i是否是质数
for (int j = 2; j < i ; j++) {
if (i % j == 0){
number++;
}
}
if (number == 0){
System.out.println(i);
}
}*/
//方式二
for (int i = 2; i <= 100 ; i++) { //遍历100以内自然数
boolean isFlag = true;
//判断i是否是质数
for (int j = 2; j < i ; j++) {
if (i % j == 0){
isFlag = false;
}
}
if (isFlag){
System.out.println(i);
}
}
}
}
100000以内
public class PrimeNumberTest {
public static void main(String[] args) {
//获取系统当前时间
long start = System.currentTimeMillis(); //总毫秒数 从1970年1月1日开始计算
boolean isFlag = true;
int count = 0; //记录质数的个数
for (int i = 2; i <= 100000 ; i++) { //遍历100000以内自然数
//判断i是否是质数
for (int j = 2; j < i ; j++) {
if (i % j == 0){
isFlag = false;
}
}
if (isFlag){
count++;
}
//重置isFlag
isFlag = true;
}
//获取系统当前时间
long end = System.currentTimeMillis();
System.out.println("质数的总个数为:" + count);
System.out.println("花费的时间为:" + (end - start));
}
}
优化
public class PrimeNumberTest {
public static void main(String[] args) {
long start = System.currentTimeMillis(); //记录当前时间距离1970-1-1 00:00:00的毫秒数
int count = 0;//记录质数的个数
for(int i = 2;i <= 100000;i++){ //i
boolean isFlag = true; //用于标识i是否被除尽过
for(int j = 2;j <= Math.sqrt(i);j++){ //优化2:将循环条件中的i改为Math.sqrt(i)
if(i % j == 0){ //表明i有约数
isFlag = false;
break;//优化1:主要针对非质数起作用
}
}
//判断i是否是质数
if(isFlag){ //如果isFlag变量没有给修改过值,就意味着i没有被j除尽过。则i是一个质数
//System.out.println(i);
count++;
}
}
long end = System.currentTimeMillis();
System.out.println("质数的个数为:" + count);
System.out.println("执行此程序花费的毫秒数为:" + (end - start));//1062
}
}
05、Scanner:键盘输入功能的实现
- 如何从键盘获取不同类型(基本数据类型、String类型)的变量:使用Scanner类。
- 键盘输入代码的四个步骤:
- 1.导包:import java.util.Scanner;
- 2.创建Scanner类型的对象:Scanner scan = new Scanner(System.in);
- 3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
- 4.释放资源:scan.close();
- 注意:需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常 导致程序终止。
5.1 各种类型的数据输入
案例1:
小明注册某交友网站,要求录入个人相关信息。如下:
请输入你的网名、你的年龄、你的体重、你是否单身、你的性别等情况。
//步骤1、导包
import java.util.Scanner;
class ScannerTest {
public static void main(String[] args) {
//步骤2:创建Scanner的对象
Scanner scan = new Scanner(System.in);
System.out.println("欢迎来到交友网!");
System.out.println("请输入你的网名: ");
//步骤3:调用Scanner类中的方法,获取指定类型的变量
String name = scan.next();
System.out.println("请输入你的年龄: ");
int age = scan.nextInt();
System.out.println("请输入你的体重: ");
double weight = scan.nextDouble();
System.out.print("你是否单身(true/false):");
boolean isSingle = scan.nextBoolean();
System.out.print("请输入你的性别(男\\女):");
char gender = scan.next().charAt(0);
System.out.println("你的基本情况如下:");
System.out.println("网名:" + name + "\n年龄:" + age + "\n体重:" + weight + "\n单身:" + isSingle + "\n性别:" + gender);
System.out.println("注册完成,欢迎继续进入体验!");
//步骤4:关闭资源,调用Scanner类的close()
scan.close();
}
}
案例2:
大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件:高:180cm以上;富:财富1千万以上;帅:是。
如果这三个条件同时满足,则:“我一定要嫁给他!!!”
如果三个条件有为真的情况,则:“嫁吧,比上不足,比下有余。”
如果三个条件都不满足,则:“不嫁!”
提示:
System.out.println(“身高: (cm));
scanner.nextInt();
System.out.println(“财富: (千万));
scanner.nextDouble();
System.out.println(“帅否: (true/false));
scanner.nextBoolean();
System.out.println(“帅否: (是/否));
scanner.next(); "是".equals(str)
//步骤1、导包
import java.util.Scanner;
class ScannerExer1 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入你的身高:(cm)");
int height = scan.nextInt();
System.out.println("请输入你的财富:(以千万为单位)");
double wealth = scan.nextDouble();
//是否帅问题,使用String类型接收
System.out.println("帅否?(是/否)");
String isHandsome = scan.next();
//判断
if(height >= 180 && wealth >= 1.0 && isHandsome.equals("是")){ //知识点:判断两个字符串是否相等,使用String的equals()
System.out.println("我一定要嫁给他!!!");
}else if(height >= 180 || wealth >= 1.0 || isHandsome.equals("是")){
System.out.println("嫁吧,比上不足,比下有余。");
}else{
System.out.println("不嫁");
}
//步骤4:关闭资源,调用Scanner类的close()
scan.close();
}
}
06、如何获取一个随机数
如何产生一个指定范围的随机整数?
- 1、Math类的random()的调用,会返回一个[0,1)范围的一个double型值
- 2、Math.random() * 100 —> [0,100) (int)(Math.random() * 100) —> [0,99] (int)(Math.random() * 100) + 5 ----> [5,104]
- 3、如何获取[a,b]范围内的随机整数呢?(int)(Math.random() * (b - a + 1))+a
- 4、举例
/*
如何产生一个随机数?
1、可以使用java提供的api:math类的random()
2、random()调用以后,会返回一个[0.0,1.0)范围的一个double型的随机数
3、需求1:获取 [0,100) 范围的随机整数
需求2:获取 [1,100) 范围的随机整数
4、需求:获取[a,b] 范围的随机整数
(int)Math.random() * (b - a + 1) + a
*/
public class RandomTest {
public static void main(String[] args) {
double d1 = Math.random();
System.out.println("d1 = " + d1);
int d2 = (int)(Math.random() * 101) ;
System.out.println("d2 = " + d2);
int d3 = (int)(Math.random() * 100) +1 ;
System.out.println("d3 = " + d3);
}
}
07、谷粒记账软件项目
目标
- 模拟实现一个基于文本界面的《谷粒记账软件》
- 掌握初步的编程技巧和调试技巧
- 主要涉及以下知识点
- 变量的定义
- 基本数据类型的使用
- 循环语句
- 分支语句
- 方法声明、调用和返回值的接收
- 简单的屏幕输出格式控制
Utility工具类
import java.util.Scanner;
/**
* Utility工具类:
* 将不同的功能封装为方法,就是可以直接通过调用方法使用它的功能,而无需考虑具体的功能实现细节
*/
public class Utility {
private static Scanner scanner = new Scanner(System.in);
/**
* 用于界面菜单的选择。该方法读取键盘,如果用户键入 ‘1-4’中任意字符,则方法返回。返回值为用户键入字符
*/
public static char readMenuSelection(){
char c;
for (; ; ){
String str = readKeyBoard(1);
c = str.charAt(0);
if (c != '1' && c != '2'&& c != '3' && c != '4'){
System.out.println("选择错误,请重新输入:");
}
else
break;
}
return c;
}
/**
* 用于收入和支出金额的输入。该方法从键盘读取一个不超过4位长度的整数,并将其作为方法的返回值
*/
public static int readNumber(){
int n;
for (; ; ){
String str = readKeyBoard(4);
try {
n = Integer.parseInt(str);
break;
}catch (NumberFormatException e){
System.out.println("数字输入错误,请重新输入:");
}
}
return n;
}
/**
* 用于收入和支出说明的输入。该方法从键盘读取一个不超过8位长度的字符串,并将其作为方法的返回值
*/
public static String readString(){
String str = readKeyBoard(8);
return str;
}
/**
* 用于确认选择的输入。该方法从键盘读取'Y'或'N',并将其作为方法的返回值
*/
public static char readConfirmSelection(){
char c;
for (; ; ){
String str = readKeyBoard(1).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N'){
break;
}else {
System.out.println("选择错误,请重新输入:");
}
}
return c;
}
private static String readKeyBoard(int limit){
String line = "";
while (scanner.hasNext()){
line = scanner.nextLine();
if (line.length() < 1 || line.length() > limit){
System.out.println("输入长度(不大于" + limit + ")错误,请重新输入:");
continue;
}
break;
}
return line;
}
}
阶段一的项目:谷粒记账软件的实现
/**
* 阶段一的项目:谷粒记账软件的实现
*/
public class GuLiAccont {
public static void main(String[] args) {
boolean isFlag = true; //控制循环结束
//初始金额
int balance = 10000;
String info = ""; //记录收支的信息
while (isFlag){
System.out.println("------------------------------------谷粒记账软件------------------------------\n");
System.out.println(" 1、收支明细");
System.out.println(" 2、登记收入");
System.out.println(" 3、登记支出");
System.out.println(" 4、退 出\n");
System.out.println(" 请选择(1-4):");
char selection = Utility.readMenuSelection();//获取用户的选项:'1' '2' '3' '4'
switch (selection){
case '1':
System.out.println("----------------当前收支明细记录-------------");
System.out.println("收支\t账户余额\t收支金额\t说 明\n");
System.out.println(info);
System.out.println("---------------------------------------------");
break;
case '2':
System.out.println("本次收入金额");
int money1 = Utility.readNumber();
if (money1 > 0){
balance += money1;
}
System.out.println("本次收入说明:");
String addDesc = Utility.readString();
info += "收入"+'\t' + balance + "\t" + "\t" + money1 + "\t" + "\t" + addDesc + "\n";
System.out.println("---------------------------登记完成---------------------------");
break;
case '3':
System.out.println("本次支出金额");
int money2 = Utility.readNumber();
if (money2 > 0 && balance >= money2){
balance -= money2;
}
System.out.println("本次支出说明:");
String minusDesc = Utility.readString();
info += "支出" +"\t"+ balance + "\t" + "\t" + money2 + "\t" + "\t"+ "\t" + minusDesc + "\n";
System.out.println("---------------------------登记完成---------------------------");
break;
case '4':
System.out.println("\n确认是否退出(Y/N):");
char isExit = Utility.readConfirmSelection();
if (isExit == 'Y'){
isFlag = false;
}
break;
}
}
}
}
08、企业中项目的研发流程
四、idea的安装与使用
五、数组
01. 数组的概述
1.1 为什么需要数组
需求分析1:
需要统计某公司50个员工的工资情况,例如计算平均工资、找到最高工资等。用之前知识,首先需要声明50个变量来分别记录每位员工的工资,这样会很麻烦。因此我们可以将所有的数据全部存储到一个容器中统一管理,并使用容器进行计算。
容器的概念:
- 生活中的容器:水杯(装水等液体),衣柜(装衣服等物品),集装箱(装货物等)。
- 程序中的容器:将多个数据存储到一起,每个数据称为该容器的元素。
1.2 数组的概念
数组(Array):是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
数组中的概念:
- 数组名
- 下标(或索引)
- 元素
- 数组的长度
数组的特点:
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间。占据的空间的大小,取决于数组的长度和数组中元素的类型。
- 数组中的元素在内存中是依次紧密排列的,有序的。
- 数组,一旦初始化完成,其长度就是确定的。数组的长度一旦确定,就不能修改。
- 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
- 数组名中引用的是这块连续空间的首地址。
1.3 数组的分类
1、按照元素类型分:
- 基本数据类型元素的数组:每个元素位置存储基本数据类型的值
- 引用数据类型元素的数组:每个元素位置存储对象(本质是存储对象的首地址)(在面向对象部分讲解)
2、按照维度分: - 一维数组:存储一组数据
- 二维数组:存储多组数据,相当于二维表,一行代表一组数据,只是这里的二维表每一行长度不要求一样。
02. 一维数组的使用
2.1 一维数组的声明
public class OneArrayTest1 {
public static void main(String[] args) {
//1、数组的声明和初始化
//复习:变量的定义格式: 数据类型 变量名 = 变量值
int num1 = 10;
int num2; //声明
num2 = 20; //初始化
//1.1声明数组
double[] prices;
//1.2数组的初始化
//静态初始化:数组变量的赋值与数组元素的赋值操作同时进行
prices = new double[]{20.23,32.98,75,48};
/* String[] foods;
foods = new String[]{"拌海蜇","龙须菜","炝冬笋"};*/
String[] foods;
foods = new String[4];
//数组的声明和初始化
//动态初始化:数组变量的赋值与数组元素的赋值操作分开进行
String[] foods2 = new String[3];
//其他正确的方式
int arr[]= new int[4];
int[] arr1 = {1, 2, 3, 4}; //类型推断
}
}
2.2 一维数组的初始化
public class OneArrayTest1 {
public static void main(String[] args) {
//1、数组的声明和初始化
//复习:变量的定义格式: 数据类型 变量名 = 变量值
int num1 = 10;
int num2; //声明
num2 = 20; //初始化
//1.1声明数组
double[] prices;
//1.2数组的初始化
//静态初始化:数组变量的赋值与数组元素的赋值操作同时进行
prices = new double[]{20.23,32.98,75,48};
/* String[] foods;
foods = new String[]{"拌海蜇","龙须菜","炝冬笋"};*/
String[] foods;
foods = new String[4];
//数组的声明和初始化
//动态初始化:数组变量的赋值与数组元素的赋值操作分开进行
String[] foods2 = new String[3];
//其他正确的方式
int arr[]= new int[4];
int[] arr1 = {1, 2, 3, 4}; //类型推断
//2、数组元素的调用
//通过角标的方式,获取数组的元素
//角标的范围[0,数组名.length - 1]
System.out.println(prices[0]);
System.out.println(prices[3]);
foods[0] = "拌海蜇";
foods[1] = "龙须菜";
foods[2] = "炝冬笋";
foods[3] = "酱茄子";
//3、数组的长度:用来描述数组容器中容量的大小
//使用length属性表示
System.out.println(foods.length);
System.out.println(prices.length);
//4、如何遍历数组
/* System.out.println(prices[0]);
System.out.println(prices[1]);
System.out.println(prices[2]);
System.out.println(prices[3]);*/
for (int i = 0; i < foods.length; i++) {
System.out.println(foods[i]);
}
for (int i = 0; i < prices.length; i++) {
System.out.println(prices[i]);
}
//5、数组元素的默认初始化值
int[] arr2 = new int[5];
System.out.println(arr2[0]);
short[] arr3 = new short[4];
for (int i = 0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
double[] arr4 = new double[3];
System.out.println(arr4[0]);
char[] arr5 = new char[4];
System.out.println(arr5[0]);
if (arr5[0] == 0){
System.out.println("111");
}
if (arr5[0] == '0'){
System.out.println("222");
}
if (arr5[0] == '\u0000'){
System.out.println("333");
}
System.out.println(arr5[0] + 1);
boolean[] arr6 = new boolean[3];
System.out.println(arr6[0]);
String[] arr7 = new String[5];
for (int i = 0; i < arr7.length; i++) {
System.out.println(arr7[i]);
}
if (arr7[0] == null){
System.out.println("aaaaaaaaa");
}
if (arr7[0] == "null"){
System.out.println("bbbbbbbbb");
}
}
}
03. 一维数组内存分析
3.1、一个一维数组内存图
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);//[I@5f150435
}
3.2、两个一维数组内存图
public static void main(String[] args) {
int[] arr = new int[3];
int[] arr2 = new int[2];
System.out.println(arr);
System.out.println(arr2);
}
3.3、两个变量指向一个一维数组
两个数组变量本质上代表同一个数组
public static void main(String[] args) {
// 定义数组,存储3个元素
int[] arr = new int[3];
//数组索引进行赋值
arr[0] = 5;
arr[1] = 6;
arr[2] = 7;
//输出3个索引上的元素值
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
//定义数组变量arr2,将arr的地址赋值给arr2
int[] arr2 = arr;
arr2[1] = 9;
System.out.println(arr[1]);
}
04. 一维数组的应用
案例1:
升景坊单间短期出租4个月,550元/月(水电煤公摊,网费35元/月),空调、卫生间、厨房齐全。屋内均是IT行业人士,喜欢安静。所以要求来租者最好是同行或者刚毕业的年轻人,爱干净、安静。
public class ArrayExer {
public static void main(String[] args) {
int[] arr = new int[]{8, 2, 1, 0, 3, 6};
int[] index = new int[]{2, 0, 4, 5, 1, 2, 3, 3, 1,2 ,4};
String tel = "";
for (int i = 0; i < index.length; i++) {
int value = index[i];
tel += arr[value];
}
System.out.println("联系方式:" + tel);
}
}
案例2:输出英文星期几
用一个数组,保存星期一到星期天的7个英语单词,从键盘输入1-7,显示对应的单词
import java.util.Scanner;
public class ArrayExer02 {
public static void main(String[] args) {
//定义包含7个单词的数组
String[] weeks = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
//从键盘获取指定的数值,使用scanner
Scanner scan = new Scanner(System.in);
System.out.println("请输入数值(1-7):");
int day = scan.nextInt();
//针对获取的数据进行判断即可
if (day < 1 || day > 7){
System.out.println("您输入的数据有误");
}else {
System.out.println(weeks[day - 1]);
}
scan.close();
}
}
案例3:从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
- 成绩>=最高分-10 等级为’A’
- 成绩>=最高分-20 等级为’B’
- 成绩>=最高分-30 等级为’C’
- 其余 等级为’D’
提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
import java.util.Scanner;
public class ArrayExer03 {
public static void main(String[] args) {
//1、从键盘输入学生的人数,根据人数,创建数组(动态初始化)
Scanner scan = new Scanner(System.in);
System.out.println("请输入学生人数:");
int count = scan.nextInt();
int[] scores = new int[count];
//2、根据提示,依次输入学生成绩,并将成绩保存在数组元素中
System.out.println("请输入这" + count + "个学生成绩");
for (int i = 0; i < scores.length; i++) {
scores[i] = scan.nextInt();
}
//3、获取学生成绩的最大值
int maxScore = 0;
//int maxScore1 = scores[0];
for (int i = 0; i < scores.length; i++) {
if (maxScore < scores[i]){
maxScore = scores[i];
}
}
System.out.println("最高分是:" + maxScore);
//4、遍历数组元素,根据学生成绩与最高分的差值,得到每个学生的等级,并输出成绩和等级
for (int i = 0; i < scores.length; i++) {
if (scores[i] >= maxScore - 10){
System.out.println("student " + (i+1) + " score is " + scores[i] + " grade is A");
}else if (scores[i] >= maxScore - 20){
System.out.println("student " + (i+1) + " score is " + scores[i] + " grade is B");
}else if (scores[i] >= maxScore - 30){
System.out.println("student " + (i+1) + " score is " + scores[i] + " grade is C");
}else {
System.out.println("student " + (i+1) + " score is " + scores[i] + " grade is D");
}
}
scan.close();
}
}
05. 多维数组的使用
5.1 概述
如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像Excel中的表格、围棋棋盘一样。
- 对于二维数组的理解,可以看成是一维数组array1又作为另一个一维数组array2的元素而存在
- 其实,从数组底层的运行机制来看,其实没有多维数组
5.2 声明与初始化
public class TwoArrayTest {
public static void main(String[] args) {
//1、数组的声明和初始化
//复习:
int[] arr1 = new int[]{1,2,3};
//方式1:静态初始化 :数组变量的赋值与数组元素的赋值操作同时进行
int[][] arr2 = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
//方式2: 动态初始化1: 数组变量的赋值与数组元素的赋值操作分开进行
String[][] arr3 = new String[3][4];
//动态初始化2
double[][] arr4 = new double[2][];
//其他正确的方式
int arr5[][] = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
int [] arr6 [] = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
int arr7[][] = {{1,2,3},{4,5},{6,7,8,9}}; //类型推断
String arr8[][] = new String[3][4];
//2、数组元素的调用
//针对arr2来说,外层元素{1,2,3},{4,5},{6,7,8,9} 内层元素 1,2,3,4,5,6,7,8,9
//调用内层元素
System.out.println(arr2[0][0]); //1
System.out.println(arr2[2][1]); //7
//调用外层元素
System.out.println(arr2[0]); //[I@4554617c 地址值
//测试arr3,arr4
arr3[0][1] = "Tom";
System.out.println(arr3[0][1]);
System.out.println(arr3[0]);
arr4[0] = new double[4];
arr4[0][0] = 1.0;
//3、数组的长度
System.out.println(arr2.length); //3
System.out.println(arr2[0].length); //3
System.out.println(arr2[1].length); //2
System.out.println(arr2[2].length); //4
//4、如何遍历数组
for (int i = 0; i < arr2.length; i++) {
for (int j = 0; j < arr2[i].length; j++) {
System.out.print(arr2[i][j] + "\t");
}
System.out.println();
}
}
}
5.3 二维数组的遍历
public class TwoArrayTest1 {
public static void main(String[] args) {
//5、数组元素的默认初始化值
//以动态初始化方式1说明:
int[][] arr1 = new int[3][2];
//外层元素默认值
System.out.println(arr1[0]); //[I@4554617c
System.out.println(arr1[1]); // [I@74a14482
//内层元素默认值
System.out.println(arr1[0][0]); // 0
boolean[][] arr2 = new boolean[3][4];
//外层元素默认值
System.out.println(arr2[0]); // [Z@1540e19d
//内层元素默认值
System.out.println(arr2[0][1]); // false
String[][] arr3 = new String[4][2];
//外层元素默认值
System.out.println(arr3[0]); // [Ljava.lang.String;@677327b6
//内层元素默认值
System.out.println(arr3[0][1]); // null
//**********************************************************
//以动态初始化方式2说明:
int[][] arr4 = new int[4][];
//外层元素默认值
System.out.println(arr4[0]); // null
//内层元素默认值
System.out.println(arr4[0][0]); //报错:空指针异常 Exception in thread “main” java.lang.NullPointerException
String[][] arr5 = new String[5][];
//外层元素默认值
System.out.println(arr5[0]); // null
//内层元素默认值
System.out.println(arr5[0][0]); //报错
}
}
5.4 内存解析
5.5 应用举例
案例1:获取arr数组中所有元素的和
public class ArrayExer01 {
public static void main(String[] args) {
//初始化数组:静态初始化
int[][] arr = {{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++) {
sum += arr[i][j];
}
}
System.out.println("总和为:" + sum);
}
}
public class ArrayExer02 {
public static void main(String[] args) {
// = : 赋值符号
int i = 10;
int j = i;
byte b = (byte)i; //强制类型转换
long l = i; //自动类型提升
//举例:数组
int[] arr1 = new int[10];
byte[] arr2 = new byte[20];
// arr1 = arr2 ; // 编译不通过,原因:int[] byte[] 是两种不同类型的引用变量
System.out.println(arr1); //[I@4554617c
System.out.println(arr2); // [B@74a14482
int[][] arr3 = new int[3][2];
// arr3 = arr1 ; // 编译不通过
arr3[0] = arr1;
System.out.println(arr3[0]); //地址值类型相同
System.out.println(arr1);
}
}
public class ArrayExer02 {
public static void main(String[] args) {
String [][] employees = new String[][]{{"10","1","段誉","22","3000"},
{"11","2","令狐冲","32","18000","15000","2000"},
{"12","3","赵敏","23","7000"}
};
System.out.println("员工类型\t编号\t姓名\t年龄\t薪资\t奖金\t股票");
for (int i = 0; i < employees.length; i++) {
String employeeType = employees[i][0];
switch (employeeType){
case "10":
System.out.print("普通员工\t");
break;
case "11":
System.out.print("架构师\t\t");
break;
case "12":
System.out.print("程序员\t\t");
break;
}
for (int j = 0; j < employees[i].length; j++) {
System.out.print(employees[i][j] + "\t");
}
System.out.println();
}
}
}
06. 数组的常见算法
6.1 数值型数组特征值统计
这里的特征值涉及到:平均值、最大值、最小值、总和等
1、求最值
/**
* 案例:定义一个int类型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,最小值,总和,平均值,并输出出来
*
* 要求:所有随机数都是两位数,[10,99]
*
*/
public class ArrayExer01 {
public static void main(String[] args) {
//1、动态初始化方式创建数组
int[] arr = new int[10];
//2、通过循环给数组元素赋值
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random() * (99 - 10 + 1)) + 10;
System.out.print(arr[i] + "\t");
}
System.out.println();
//3.1、求最大值
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]){
max = arr[i];
}
}
System.out.println("最大值为:" + max);
//3.2、求最小值
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (min > arr[i]){
min = arr[i];
}
}
System.out.println("最大值为:" + min);
//3.3、求总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("总和为:" + sum);
//3.4、求平均值
int avgValue = sum / arr.length;
System.out.println("平均值为:" + avgValue);
}
}
2、评委打分
/**
* 评委打分
*
* 在编程比赛中,10位评委打分: 5,4,6,8,9,8,1,2,7,3
* 求最后得分,去掉一个最高分一个最低分
*
*/
public class ArrayExer01 {
public static void main(String[] args) {
int[] scores = {5,4,6,8,9,8,1,2,7,3};
//声明三个特征值
int sum = 0;
int max = 0;
int min = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i]; //累加总分
//获取最高分
if (max < scores[i]){
max = scores[i];
}
//获取最低分
if (min > scores[i]){
min = scores[i];
}
}
int avg = (sum - max - min) / (scores.length - 2);
System.out.println("去掉一个最高分一个最低分之后,平均分为:" + avg);
}
}
3、杨辉三角
/**
* 杨辉三角
*
* 使用二维数组打印一个 10 行杨辉三角。
* 提示:
* 18.第一行有 1 个元素, 第 n 行有 n 个元素
* 19.每一行的第一个元素和最后一个元素都是 1
* 20.从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
* yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
*
*/
public class ArrayExer01 {
public static void main(String[] args) {
//1、创建二维数组
int[][] yanghui = new int[10][];
//2、使用循环结构,初始化外层数组元素
for (int i = 0; i < yanghui.length; i++) {
yanghui[i] = new int[i + 1];
//3、给数组的元素赋值
//3.1、给数组每行的首末元素赋值为1
yanghui[i][0] = yanghui[i][i] = 1;
//3.2、给数组每行的非首末元素赋值
for (int j = 1; j < yanghui[i].length - 1; j++) { //j从每行第二个元素开始,到倒数第2个元素结束
yanghui[i][j] = yanghui[i - 1][j] + yanghui[i -1][j - 1];
}
}
//遍历二维数组
for (int i = 0; i < yanghui.length; i++) {
for (int j = 0; j < yanghui[i].length; j++) {
System.out.print(yanghui[i][j] + "\t");
}
System.out.println();
}
}
}
4、遍历扑克牌
遍历扑克牌,效果如图所示:
提示:使用两个字符串数组,分别保存花色和点数,再用一个字符串数组保存最后的扑克牌。
String[] hua = {“黑桃”,“红桃”,“梅花”,“方片”};
String[] dian = {“A”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”,“10”,“J”,“Q”,“K”};
public class ArrayExer01 {
public static void main(String[] args) {
String[] hua = {"黑桃","红桃","梅花","方片"};
String[] dian = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
String[] pai = new String[hua.length * dian.length];
int k = 0;
for(int i = 0;i < hua.length;i++){
for(int j = 0;j < dian.length;j++){
pai[k++] = hua[i] + dian[j];
}
}
for (int i = 0; i < pai.length; i++) {
System.out.print(pai[i] + " ");
if (i % 13 == 12) {
System.out.println();
}
}
}
}
5、回形数
从键盘输入一个整数(1~20) ,则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。
例如: 输入数字2,则程序输出:
1 2
4 3
输入数字3,则程序输出:
1 2 3
8 9 4
7 6 5
public class RectangleTest1 {
public static void main(String[] args) {
int n = 7;
int[][] arr = new int[n][n];
int count = 0; //要显示的数据
int maxX = n-1; //x轴的最大下标
int maxY = n-1; //Y轴的最大下标
int minX = 0; //x轴的最小下标
int minY = 0; //Y轴的最小下标
while(minX<=maxX) {
for(int x=minX;x<=maxX;x++) {
arr[minY][x] = ++count;
}
minY++;
for(int y=minY;y<=maxY;y++) {
arr[y][maxX] = ++count;
}
maxX--;
for(int x=maxX;x>=minX;x--) {
arr[maxY][x] = ++count;
}
maxY--;
for(int y=maxY;y>=minY;y--) {
arr[y][minX] = ++count;
}
minX++;
}
for(int i=0;i<arr.length;i++) {
for(int j=0;j<arr.length;j++) {
String space = (arr[i][j]+"").length()==1 ? "0":"";
System.out.print(space+arr[i][j]+" ");
}
System.out.println();
}
}
}
6.2 赋值、复制
使用简单数组
赋值
public class ArrayExer01 {
public static void main(String[] args) {
//(1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
int[] array1,array2;
//(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
array1 = new int[]{2,3,5,7,11,13,17,19};
//(3)显示array1的内容。
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
//(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
array2 = array1;
for (int i = 0; i < array2.length; i++) {
if (i % 2 == 0){
array2[i] = i;
}
}
System.out.println(); //换行
System.out.println(array1);
System.out.println(array2);
// 打印出array1。
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
}
}
思考:array1和array2是什么关系?
a:array1 和 array2 是两个变量,共同指向了堆空间中的同一个数组结构,即二者的地址值相同
复制
public class ArrayExer01 {
public static void main(String[] args) {
//(1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
int[] array1,array2;
//(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
array1 = new int[]{2,3,5,7,11,13,17,19};
//(3)显示array1的内容。
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
//(4)复制array1数组给array2,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
array2 = new int[array1.length];
for (int i = 0; i < array1.length; i++) {
array2[i] = array1[i];
}
System.out.println(); //换行
System.out.println(array1);
System.out.println(array2);
for (int i = 0; i < array2.length; i++) {
if (i % 2 == 0){
array2[i] = i;
}
}
// 打印出array1。
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
}
}
6.3 数组元素的反转
实现思想:数组对称位置的元素互换
案例:
定义数组: int[] arr = new int[]{23,55,78,45,84,95};
实现数组元素的反转存储
public class ArrayExer01 {
public static void main(String[] args) {
int[] arr = new int[]{23,55,78,45,84,95};
//遍历
for (int i = 0; i < arr.length ; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
//反转操作
//方式1:
/* for (int i = 0; i < arr.length / 2; i++) {
//交换 arr[i] 与 arr[arr.length - i - 1] 位置的元素
int temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i ] = temp;
}*/
//方式2:
for (int i = 0 , j = arr.length -1; i < j ; i++,j--) {
//交换 arr[i] 与 arr[j] 位置的元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/* //方式3: 不推荐
int[] newArr = new int[arr.length];
for (int i = arr.length - 1; i >= 0 ; i--) {
newArr[arr.length -1 -i] = arr[i];
}*/
arr = newArr;
//遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
6.4 数组的扩容与缩容
数组的扩容
题目:现有数组 int[] arr = new int[]{1,2,3,4,5}; ,现将数组长度扩容1倍,并将10,20,30三个数据添加到arr数组中
public class ArrayExer01 {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
//扩容1倍容量
int[] newArr = new int[arr.length * 2];
//或
int[] newArr1 = new int[arr.length << 1];
//将原有数组中的元素复制到新的数组中
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i];
}
//将10,20,30三个数据添加到新的数组中
newArr[arr.length] = 10;
newArr[arr.length + 1] = 20;
newArr[arr.length + 2] = 30;
//将新的数组的地址赋值给原有的数组变量
arr = newArr;
//遍历arr
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
数组的缩容
题目:现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素。
public class ArrayExer01 {
public static void main(String[] args) {
int[] arr={1,2,3,4,5,6,7};
int deleteIndex = 4;
/* //方式1:不新建数组
for (int i = deleteIndex; i < arr.length -1; i++) {
arr[i] = arr[i +1];
}
//修改最后元素,设置为默认值
arr[arr.length -1] = 0;*/
//方式2:新建数组,新的数组长度比原有数组的长度少一个
int[] newArr = new int[arr.length -1];
for (int i = 0; i < deleteIndex; i++) {
newArr[i] = arr[i];
}
for (int i = deleteIndex; i < arr.length -1; i++) {
newArr[i] = arr[i + 1];
}
arr = newArr;
//遍历arr数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
6.5 数组的元素查找
1、顺序查找
(线性查找)
优点:算法简单
缺点:效率低。执行的时间复杂度0(n)
定义数组:int[] arr = {4,5,6,1,34,12,15,9};
查找元素5是否存在,如果存在,输出对应的索引值
public class ArrayExer01 {
public static void main(String[] args) {
int[] arr = new int[]{4,6,1,17,34,2,5,12,15,9};
int target = 5;
/* //方式1:
//查找方法:线性查找
boolean isFlag = true;
for (int i = 0; i < arr.length ; i++) {
if (target == arr[i] ){
System.out.println("找到了" + target + ",对应位置为:" + i);
isFlag = false;
break;
}
}
if (isFlag){
System.out.println("不好意思,没有找到此元素");
}*/
//方式2:
int i = 0;
for (; i < arr.length; i++) {
if (target == arr[i]){
System.out.println("找到了" + target + ",对应位置为:" + i);
break;
}
}
if (i == arr.length){
System.out.println("不好意思,没有找到此元素");
}
}
}
2、二分查找
优点:执行效率高
缺点:算法相对于顺序查找难一点,前提,数组必须有序
实现步骤:
举例
定义数组:int[] arr = {4,5,6,25,34,12,15,9};
查找元素5是否存在,如果存在,输出对应的索引值
public class ArrayExer01 {
public static void main(String[] args) {
int[] arr = {4,5,6,1,25,34,12,15,9};
int target = 5;
int head = 0; //默认的首索引
int end = arr.length -1; //默认的尾索引
boolean isFlag = true; //判断是否找到了指定元素
while (head <= end){
int middle = (head + end) / 2;
if (target == arr[middle]){
System.out.println("找到了" + target + ",对应的位置为:" + middle);
isFlag = false;
break;
}else if (target > arr[middle]){
head = middle + 1;
}else { //target < arr[middle]
end = middle - 1;
}
}
if (isFlag){
System.out.println("不好意思,没有找到");
}
}
}
第二阶段:Java面向对象编程
六、面向对象编程(基础)
本章专题与脉络
01、面向对象编程概述(了解)
1.1 面向对象与面向过程的区别
学习面向对象内容的三条主线
- Java类及类的成员:(重点)属性、方法、构造器;(熟悉)代码块、内部类
- 面向对象的特征:封装、继承、多态、(抽象)
- 其他关键字的使用:this、super、package、import、static、final、interface、abstract等
1、面向过程的程序设计思想(Process-Oriented Programming),简称POP
- 关注的焦点是过程:过程就是操作数据的步骤。如果某个过程的实现代码重复出现,那么就可以把这个过程抽取为一个函数。这样就可以大大简化冗余代码,便于维护。
- 典型的语言:C语言
- 代码结构:以函数为组织单位。
- 是一种“执行者思维”,适合解决简单问题。扩展能力差、后期维护难度较大。
2、 面向对象的程序设计思想( Object Oriented Programming),简称OOP
- 关注的焦点是类:在计算机程序设计过程中,参照现实中事物,将事物的属性特征、行为特征抽象出来,用类来表示。
- 典型的语言:Java、C#、C++、Python、Ruby和PHP等
- 代码结构:以类为组织单位。每种事物都具备自己的属性和行为/功能。
- 是一种“设计者思维”,适合解决复杂问题。代码扩展性强、可维护性高。
1.2 二者的关系
我们千万不要把面向过程和面向对象对立起来。他们是相辅相成的。面向对象离不开面向过程
02、面向对象的两个核心概念:类(Class)和对象(Object)
- 类:具有相同特征的事物的抽象描述,是抽象的、概念上的定义。
- 对象:实际存在的该类事物的每个个体,是具体的,因而也称为实例(instance)。
类 => 抽象概念的人;对象 => 实实在在的某个人
2.1 类的成员概述
- 面向对象程序设计的重点是类的设计
- 类的设计,其实就是类的成员的设计
- Java代码世界是由诸多个不同功能的类构成的。
Java中用类class来描述事物也是如此。类,是一组相关属性和行为的集合,这也是类最基本的两个成员。
属性:该类事物的状态信息。对应类中的成员变量
- 成员变量 <=> 属性 <=> Field
行为:该类事物要做什么操作,或者基于事物的状态能做什么。对应类中的成员方法 - (成员)方法 <=> 函数 <=> Method