一、流程控制语句
if语句格式2
if(条件表达式)
{
语句1;
}else{
语句2;
}
1.1 If…else格式和三元运算符的区别(面试题)
三元运算符只是一个运算符号,不是流程控制语句,在三元中不能输出打印值,可以操作具体的数据值(结果最终是数据值);
而if...else...流程控制语句,范围远远大于三元运算符,既可以使用具体数据值,也可以是打印内容;
三元运算符能够使用的一定能够用if...else...实现;
if...else...能够实现的,不一定能够使用三元!
if嵌套
if(表达式1){
if(表达式2){
语句1;
}else{
语句2;
}
}else{
if(表达式3){
语句3;
}else{
语句4;
}
}
if语句格式3
if格式3:
if(表达式1){
语句1;
}else if(表达式2){
语句2;
...
}else{
语句n;
}
执行流程:
1)先判断表达式1是否成立,成立,则执行语句1
2)不成立,则判断表达式2是否成立,成立,执行语句2;
否则依次...进行判断
...
3)如果上面都不成立,则执行else语句,最终结束;
场景:
针对多种进行判断!
switch语句
switch语句格式
switch(表达式){
case 值1:
语句1;
break;
case 值2:
语句2;
break;
,,,,
,,,,,
default:
语句n;
break;
}
执行流程
1)表达式中的值先和case值1比较,如果匹配,执行语句1,语句break,语句结束;
2)case值1不匹配,继续和case值2进行比较,如果一致,执行语句2,swich结束;
...
...
3)如果上面的case的值和表达式中的结果值都不匹配,执行default语句,执行语句n,switch语句结束;
4.1 switch语句后面的表达式的数据类型情况
基本类型:byte,int,short,char
Jdk5版本以后,表达式可以是:枚举enum(引用类型)
Jdk7版本以后,表达式可以是字符串
String(属于特殊的引用型)
4.2 switch语句的注意事项
1 case语句里面是有break,会造成"case穿透"
2 case语句后面的值只能是常量,不能是变量值
(Java 是一个强类型语言:语法结构非常严谨)
3 关于default语句:
1>它可以在语句中的任何位置,不影响switch语句的执行流程!
2>但是如果在语句中,那么break不要省略!(考点)
3>如果default语句它在语句的末尾,break可以省略
4 switch语句的结束条件:
1>语句break结束
2>程序默认执行到末尾!(顺序结构语句都是依次由上而下,末尾结束!)
4.3 switch语句举例
判断月份
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入月份:");
int a = sc.nextInt();
switch (a) {
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
case 12:
case 1:
case 2:
System.out.println("冬季");
break;
default:
System.out.println("请输入合法数据!");
break;
}
}
}
流程控制语句- for循环
5.1 使用for循环场景
1>见到这种代码重复性很高(冗余度很大)
2>有明确的范围
5.2 for循环格式
for(初始化语句;条件表达式;控制体语句或步长语句){
循环体语句;
}
5.3 for循环执行流程
1)先初始化语句进行赋值
2)判断条件表达式是否成立,如果成立,执行循环体语句
2.1)继续执行控制台语句或者步长语句 对初始化语句的变量进行自增或者自减
2.2)继续判断条件表达是否成立,如果成立,按照上面 这种方式执行;
2.3)如果变量自增或者自减到条件表达式不成立为止,循环语句结束!
5.4 for循环举例--水仙花数
public class shuixianhua {
public static void main(String[] args) {
for(int i=100;i<1000;i++){
int ge = i % 10;
int shi = i / 10 % 10;
int bai = i / 10 / 10 % 10;
if(ge*ge*ge+shi*shi*shi+bai*bai*bai==i){
System.out.println(i);
}
}
}
}
5.5 for循环举例--n*n乘法表
import java.util.Scanner;
public class nnTable {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入n:");
int n = sc.nextInt();
for(int i = 1;i<=n;i++){
for (int j = 1;j<=i;j++) {
System.out.print(j + "*" + i+ "=" + (i * j) + "\t" );
}
System.out.println();
}
}
}
5.6 for循环举例--百钱买百鸡
问题描述
我国古代数学家张丘建在《算经》一书中提出的数学问题:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。
百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
意思就是公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,用100文钱买一百只鸡, 其中公鸡,母鸡,小
鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱。
问题分析
设x为公鸡个数,y为母鸡个数,z为小鸡个数。
如果100钱全部都买公鸡,最多可以买20只,所以第一个循环x的范围最大是20.
如果100钱全部都买母鸡,最多可以买33只,所以第二个循环y的范围最大是33.
枚举出买各种鸡的个数,算出总钱数是否等于100.
小鸡的数量:z = 100 - x - y ;
条件:
5x+3y+z/3 == 100 并且 z % 3 == 0
代码实现
class ChickenNumTest{
public static void main(String[] args){
//定义公鸡,母鸡,小鸡的 变量
//int x,y,z ;
//for循环
for(int x = 0; x < 20 ; x ++ ){//穷举公鸡
for(int y = 0 ; y < 33 ; y ++){//穷举母鸡
//小鸡数量
int z = 100 - x - y
//满足条件
if((5*x+3*y+z/3)==100 && (z % 3 ==0) ){
System.out.
println("公鸡有:"+x+"只"+",母鸡有:"+y+"只"+",小鸡有:"+z+"只") ;
}
}
}
}
}
5.7 for循环举例--质数判断
需求:键盘录入一个正整数x,判断该数是否为一个质数
问题分析:
质数:
除了1和他自身外,不能被其他数据整除的!
如果录入的数据开平方根,这个不适用于过大的整数!(范围较小)
代码实现
//核心代码体现
假设思想:
定义变量
boolean flag = true ;
录入一个整数x
if(x<2){
flag = false ; //不是质数
}
//提高计算效率: java.lang.Math :开平方根 Math.sqrt(x))
for(int i = 2 ;i <= Math.sqrt(x);i++){
//判断:
//当期x & i == 0
flag = false ;
}
if(flag){
//质数
}else{
//不是质数
}
流程控制语句-while循环
6.1 使用while循环场景
1>不明确循环次数,使用while循环
6.2 while循环格式
基本格式:
while(条件表达式){
循环体语句;
控制体语句或者步长语句;
}
扩展格式:(使用多)
初始化语句:
while(条件表达式){
循环体语句;
控制体语句或者步长语句;
}
6.3 while循环执行流程
执行流程:
1)初始化语句进行变量赋值
2)判断条件表达式是否成立,
成立,执行循环体语句,依次执行控制体语句(对变量控制)
继续回到2)进行判断
...
...
3)条件表达式不满足,循环结束!
for和while的区别
共同点:都是使用循环思想解决一些问题
不同点:
1)格式本身不同
for(初始化语句;条件表达式;控制体语句){
循环体语句;}
初始化语句;
while(条件表达式){
循环体语句;
控制体语句;
}
2)是否明确循环次数
for循环:明确循环次数优先for循环,(for还是很频繁使用的)
while循环:不明确循环次数,使用while循环
3)从内存角度考虑销毁不同:
for循环结束,里面的变量及时释放了,所以不能在访问for中的变量
while循环结束,依然可以访问里面变量,所以消耗资源相对for循环大一些!
7.1 for和while的两种死循环
常见大的两种死循环体格式
for(;;){
循环体,,,
}
while(true){
循环体,,,
}
利用死循环解决一些问题!
死循环:肯定需要利用一些条件,当达到某种条件的时候,结束循环break;中断,结束!
举例(需求描述)
需求:
键盘录入int类型的数据,猜数字游戏(1-100之间的数据!)
提示:
jdk提供了一个类java.lang.Math(不需要导包):数学运算的工具
random()这个函数可以获取[0.0,1.0)的随机数 (常用类讲)
分析(问题分析)
分析:
1)产生一个1-100之间的随机数(利用jdk提供Math完成)--number
while(true){
2)不断的创建键盘录入对象,录入int类型的数据--guessNumber
3)判断
如果guessNumber > number ,提示数据大了
否则如果guessNumber < number ,提示数据小了
最终,一致! 结束循环,break(中断,结束);
}
实现(代码实现)
//先去使用Math类产生随机数--public static double random()
/*
for(int x = 1 ; x <=10 ;x++){
//0.0-1.0的随机数:取不到1.0
//double number = Math.random() ;
//1-100的随机数 int
int number = (int)(Math.random()*100+1);
System.out.println(number) ;
}
*/
import java.util.Scanner ;
class WhileTest3{
public static void main(String[] args){
//1)产生一个1-100之间的随机数(利用jdk提供Math完成)--number
int number = (int)(Math.random()*100+1) ;
System.out.println("猜数字游戏开始了...") ;
//定义一个统计变量
int count = 0 ;
while(true){
//统计变量++
count ++ ;
//2)创建键盘录入对象
Scanner sc = new Scanner(System.in ) ;
//3)提示并录入数据
System.out.println("请您输入要猜的数据:") ;
int guessNumber = sc.nextInt() ;
if(guessNumber<1 || guessNumber>100){
System.out.println("您输入的数据不合法!") ;
}else if(guessNumber > number){
System.out.println("您要猜的数据"+guessNumber+"大了") ;
}else if(guessNumber < number){
System.out.println("您要猜的数据:"+guessNumber+"小了") ;
}else{
System.out.println("恭喜您,第"+count+"次,猜对了!") ;
break ;//满足条件,结束死循环
}
}
}
}
8.流程控制语句--do,,,while
8.1 使用do,,,while循环场景
1>循环开发中很少使用这个格式 (jdk源码会用的!)
8.2 do,,,while循环格式
初始化语句;
do{
循环体语句;
控制体语句;
}while(条件表达式) ;
8.3 do,,,while循环执行流程
执行流程:
1)初始化语句进行赋值
2)循环体语句,--->-完成条件判断---控制体语句
继续判断,当条件不满足,循环结束!
3)如果条件直接不满足,循环体至少执行一次;
这也是for/while最大的区别
9. 跳转控制语句
😈break 直接跳出循环
😈两种应用场景:
1)循环语句中使用,结束循环用的
2)switch语句中使用,结束switch
😃continue 中断本次循环,直接进入下次循环
😕return 返回
很少单独去使用(不建议),后面一般会有返回结果值
😕retuen应用场景:
在java中的方法(函数)中去使用,目的就是结束这个方法,并且还有返回结果。
10. 键盘录入next()和nextLine()区别
next()
next()方法在读取输入内容时,会过滤掉有效字符前面的无效字符,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其过滤掉;只有在读取到有效字符之后,next()方法才将其后的空格键、Tab键或Enter键等视为结束符;
所以next()方法不能得到带空格的字符串
nextLine()
nextLine()方法的结束符只有Enter键,不会过滤输入文字前的空格和其他键值
❤️nextLine()自动读取了被next()去掉的Enter作为他的结束符,所以没办法从键盘输入值。
二、方法
2.1方法的定义
方法:就是一个代码块{ },给{ }起一个名字(方法名),然后方法中逻辑书写,以后见到同样一个功能
代码块,直接调用方法名即可。
2.2有返回值的方法
2.2.1 有返回值方法的格式
1)有返回值类型的方法的定义
Public static 返回值类型 方法名(参数类型1 参数名,参数名1,参数类型2){
//完成方法的逻辑
return 结果;
}
前面固定 | public static |
返回值类型 | 也就是数据类型(现在研究的基本数据类型) |
方法名 | 就是满足标识符的命名规则:见名知意(小驼峰命名法) |
形式参数类型 | 也是数据类型(目前:基本数据类型) |
参数名 | 就是变量名 |
2.2.2 有返回值方法调用
有返回值类型的方法调用
1)单独调用 ---方法名(实际参数列表) ; (有返回类型的方法不能使用)
2)输出调用 ---System.out.println(方法名(实际参数列表)) ;
输出调用:可以,写死了,如果相对结果值在进行操作,就不能用了
3)赋值调用:(推荐)
2.2.3 有返回值方法调用的注意事项
方法和方法平级关系,不能在一个方法中去定义另一个方法!
定义方法的返回值类型和main方法中调用方法的时候,接收结果类型不匹配!
Java是强类型语言,在定义的方法时候,形式参数名前面必须有参数类型
必须有return语句,没有就会编译报错!
定义方法的时候,有{号地方不能有分号;有分号;,不能有{左大括号
2.3没有返回值的方法
2.3.1没有返回值方法的格式
没有具体返回值类型的方法的定义格式:(没有return语句)
Public static void 方法名(形式参数类型1 形式参数1,形式参数2 形式参数){
//完成方法体逻辑
//输出内容....
}
2.3.2没有返回值方法的调用
调用方法:
1)赋值调用和输出调用 都使用不了
2)推荐:单独调用
2.4方法重载
2.4.1 方法重载的定义
java中如果方法名相同,参数列表不同,与返回值无关---这一系列的方法都称为"方法重载OverLoad"
参数列表不同
1)参数个数不同
2)参数类型不同
3)考虑参数类型的先后顺序
2.4.2方法重载的意义
为了提高这个方法的使用率,让这个方法在任何场景下都能使用同一个方法,可以传递不同类型的数据
2.5形参🙌(重点)
jvm(java虚拟机)大体为5部分
栈内存:
存储的是局部变量(在方法定义中以及方法声明上的变量)
局部变量生命周期:随着调用而存在,随着方法调用结束而消失
方法的形式参数如果是借本数据类型,形式的 参数改变,不会实际 参数。
堆内存:
new出来东西(实例--也成为”对象“:面向对象中讲 都存储在堆中)
方法区:
字节码文件区域 --里面就存储很多方法
每个方法(加载进栈内存--”栈帧“)
静态区域:static 相关的(面向对象中讲)
常量区
本地方法区:
跟系统相关
pc寄存器(程序计数器):跟系统和cpu都有关系
三、数组
3.1数组的定义
java提供的一种容器--可以存储同一类型的元素
3.2 数组的格式
定义格式:
数据类型[ ] 数组名称;
数据类型 数组名称[ ];
3.2.1动态初始化
给定数组长度,系统(jvm)默认分配数组元素内容;
A格式:
数据类型[] 数组名称 = new 数据类型[数组长度] ;
数据类型 数组名称[] = new 数据类型[数组长度] ;
举例:
int[] arr = new int[3] ;
B在数组如何确定元素的内容
数组名称[索引值(角标值)]:从0开始
动态初始化
数据类型[] 数组名称 = new 数据类型[数组长度] ;
int[] arr = new int[3] ;
=左边:
int[] :定义一个int类型的数组
arr:变量名(满足标识符的规则) arr变量(数组名称arr)
=右边
new:在堆内存中开辟空间(创建对象)
int[]:在堆内存中创建一个int类型的数组
3:在堆内存中创建数组,长度为3
System.out.println(arr) ;
输出结果为:[I@6d06d69c
[:表示是一个数组
@:地址值标记
6dxxx 具体十六进制转
创建一个数组对象的内存图解
创建多个对象内存图解_不同的栈指向同一个堆
3.2.2静态初始化
给定数组元素,长度由系统给定
原本格式:
数据类型[ ] 数组名称 = new 数据类型[ ]{元素1,元素2,元素3…….};
数据类型 数组名称[ ] = new 数据类型[ ] {元素1,元素2,元素3…….};
简写格式
数据类型[] 数组名称 ={元素1,元素2,元素3....} ;
数据类型 数组名称[] = {元素1,元素2,元素3....} ;
举例:
int[] arr = {1,2,3} ;
arr[0] = 1 ;
arr[1] = 2 ;
arr[2] = 3 ;
注意事项:
不能既动态初始化,又静态初始化(动静结合 )
int[] arr = new int[3]{1,2,3} ;//错误
3.3 数组的优点和弊端
优点:
1)“容器”可以很多元素
2)通过数组动态初始化进行元素赋值
弊端:
无论是动态初始化还是静态初始化,长度是固定的!
必须是连续空间存储(内存区域要求,不满足连续空间,无法存储)
3.4异常
1.编译时期异常:由于语法格式存在问题,导致的
2.运行时期异常:由于代码逻辑不严谨,导致问题!
❤️【1】ArraryIndexOutBoundsException:数组角标越界异常
原因:访问了数组中不存在的角标(数组中最大角标值(索引值)=数组长度-1)
解决办法:检查代码,更改角标
❤️【2】java.lang.NullPointerException:空指针异常
原因:当前某个对象为null,还有使用这个对象访问它的里面的内容,就会出现空指针
解决方案:使用这个对象之前,先对它进行非空判断,防止出现空指针!
3.5 查表法
通过数组名称[索引值]:查询元素
举例:(需求)
键盘录入一个数据,输出对应的星期值
问题分析
分析:
定义一个字符串数组
数据类型[] 数组名称={元素内容}
String[]strArray={"星期一","星期二,"星期三,"星期四","星期五","星期六","星期日'
代码实现
public class {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//提示并录入数据
System.out.println("请输入一个数据0一6")
//创建一个字符串数组
int weekValue = sc.nextInt();
String[] strArray={"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
System.out.println("你要查询的是:"+strArray[weekValue]);
3.6 索引值
数组的基本元素查找查询数组中元素第一次出现索引值
需求
数组的基本元素查找查询数组中元素第一次出现索引值
己知:
int[]arr={25,67,13,66,89,76}
需求:查询13第一次出现的索引值;
(考虑:查询到了,返回角标;没有没有查询到,也需要返回!)
查询130
需求分析
3.7 排序算法--冒泡排序
思想
两两比较,将较大的值往后放,第一次比较完毕,最大值出现在最大索引处!依次这样比较,可以得到一个排好序的数组!
实现
核心代码体现:
for(int x = 0; x< arr.length-1 ;x++){
for(int y = 0;y<arr.length-1-x;y++){
if(arr[y]>arr[y+1]){
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
3.8方法的形式参数基本数据类型和引用数据类型的区别
形式参数如果是基本数据类型,形式参数不会影响实际参数----特殊的引用类型String和这个效果一致!
如果是引用数据类型(除过String),形式参数的改变直接影响实际参数。
基本数据类型:不需要被Jvm加载
引用数据类型:类,数据。接口---->
class Student{}------>被Jvm加载(需要编译---运行时期)
四、面向对象
4.1 思想特点
1)更符合生活中的思想行为习惯
2)让复杂的事情简单化
3)让我们从执行者变成指挥者(角色变化)
4.2三大特征
封装
继承
多态
4.3类和事物/-----对象/具体事物
类:
是描述现实世界事物的一组“属性”和“行为”的集合!
一个事务---->定义一个类
类和事物:------一一对应
4.4封装
将一个事物的属性私有化(对外界隐藏,private)--->保证数据的安全性
对外提供公共的成员访问方法:setXXX(传参)/getXXX(),来对成员属性进行操作!
以后在书写 事物(对应的类:手机类/用户类等等,只要描述它的属性和行为)
成员变量(属性)---->全部私有化!
4.4.1 private关键字的特点
1)被Private修饰的成员变量/成员方法(非静态),只能在本类中访问,外界类不能访问!
2)虽然被私有修饰的成员变量以及成员方法(非静态)
不能直接访问,但是都可以间接通过“public”去访问。
4.4.2 关键字this
java提供了一个关键字:(局部变量名称隐藏了成员变量的名称)
this---->代表当前类的对象的地址值。----->this,成员变量名 = 局部变量名
4.5 局部变量和成员变量的区别
1.类中书写位置不同
局部变量位置:方法定义中,或者方法声明中
成员变量的位置:在类中,方法外
2.jvm内存位置不同
成员变量:在堆内存中
局部变量:在栈内存中
3)生命周期不同
局部变量:随着方法的调用而存在,随着方法的调用结束而消失
成员变量:不会立即消失,随着对象的创建而存在!随着对象的创建完毕并且使用完,等待来及回收期回收(不会立即回收)而消失!
4)初始化值不同:
成员变量:存在系统默认初始化,也可以显示初始化
局部变量:不能不给初始值,总之,在使用局部变量之前,必须赋值,不赋值不行。要么先定义后赋值,要么 直接给初始值。
4.6构造函数
1)方法名和类名一致
2)没有具体返回值类型
3)没有void
4.6.1构造方法格式
格式:
public 方法名(){
无参构造方法
/*
public Student(){
System.out.println("这是Student的无参构造方法") ;
}
*/
4.6.2构造方法作用
给类的成员进行数据初始化!
4.6.3构造方法(有参无参)注意事项
1)一个类中,如果没有任何构造方法,那么系统(jvm)自动会给我们提供无参构造方法!
2)一个类中,只提供有参构造方法,那么系统不会无参构造方法,此时,建议我们永远给出无参构造方法!否则,就出现问题!
4.7面试题:简述Student s = new Student(); 这个过程完成了哪些事?
加载Student.class字节码文件(类就加载一次)。
在栈内存中Student类型的变量s开辟栈内存空间。
在堆内存中申请空间地址。
在堆内存中给Student类的所有成员进行默认初始化。
再通过构造方法进行数据初始化。
默认初始化完成,产生一个堆内存空间地址。
将堆内存空间地址值赋给栈内存的这个变量。
栈内存的变量s指向堆内存地址!