文章目录
B)switch
- switch语句格式:
switch(表达式){
case 值1:
语句1;
break ;
case 值2:
语句2;
break ;
...
...
default:
语句n;
break ;
}
- 执行流程:
1)使用switch中的表达式结果和case的进行匹配
2)case语句值1,匹配了,就执行语句1,break,结束switch语句
3)值1不匹配,继续判断值2是否和switch中的值匹配,
4)如果匹配了,执行语句2,break,结束switch语句
5)如果上面都是不匹配,最终执行default语句,语句n,break结束! - switch语句中表达式可以是什么数据类型?
switch语句中的表达式可以是什么样的数据类型:
基本数据:int,byte,short,char
JDK5以后可以跟枚举 enum
JDK7以后可以跟String类型
- switch语句使用的注意事项:
1)case语句后面的值只能是常量,不能是变量(Java是一个强类型语言的:语法结构非常严谨)
javascript语言(前端):弱类型语言: switch语句的case后面既可以是常量,也可以是变量
2)书写switch语句的时候,case语句必须存在break语句,结束switch语句的!
如果没有书写break语句,会造成"case穿透!"现象
3)switch语句的结束条件
a)遇见break结束
b)程序默认执行末尾结束
4)default语句:可以在switch语句中的任何位置
如果在语句中,必须携带break; 否则case穿透
如果在语句的末尾,break是可以省略的,不建议!
switch和while(true)循环使用:
break只能结束switch,
结束while(true): system.exit(0) ;
switch语句的合并:
键盘录入月份的值(默认int),请使用switch来完成,判断季节
3,4,5 春季
6,7,8 夏季
9,10,11 秋季
12,1,2冬季
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入一个月份的值:") ;
int month = sc.nextInt() ;
//使用switch语句接受数据
switch(month){
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 ;
}
3.循环结构语句
A)for
- 引入循环语句之for的格式
for(初始化语句;条件表达式;步长/控制体语句){
循环体语句;
}
- 执行流程:
1)执行初始化化语句:给变量进行赋值
2)满足条件:成立
3)执行循环体语句
4)执行步长/控制体语句
再次执行2)过程,判断条件是否成立
依次循环
…
…
当条件表达式不成立,则for语句结束! - 统计所有的水仙花数有多少个?
统计思想:
1)定义统计变量:int count = 0 ;
2)水仙花数:三位数:100-999之间
3)通过for循环获取每一个数据
4)获取这个数据的个位,十位,百位的数据
5)满足条件:gegege+shishishi+baibaibai == x 统计变量++ ;
6)最终输出统计变量即可
//定义统计变量
int count = 0 ;
//水仙花的范围
for(int x = 100 ; x < 1000; x ++){
//获取每个位的数据本身
int ge = x % 10 ;
int shi = x /10 % 10 ;
int bai = x /10 /10 % 10 ;
//进行判断
if(x==(ge*ge*ge+shi*shi*shi+bai*bai*bai)){
System.out.println(x) ;
//统计变量++
count ++ ;
}
}
System.out.println("水仙花数共有"+count+"个") ;
for循环嵌套
一个for循环语句作为另一个for循环语句的循环体
for(初始化语句;条件表达式;控制体语句){
for(初始化语句;条件表达式;控制体语句){
}
}
- 需求:百钱买百鸡
100文钱
公鸡 5文一只
母鸡 3文一只
小鸡 一文钱三只- 穷举法
分析:
定义公鸡,母鸡,小鸡 ,分别x,y,z来表示
公鸡的数量: 0,20 (穷举法) 外层循环
母鸡的数量: 0,33(穷举):内层循环
小鸡的数量:z = 100 - x - y ;
条件:
5x+3y+z/3 == 100 并且 z % 3 == 0
- 穷举法
//定义公鸡,母鸡,小鸡的 变量
//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+"只") ;
}
}
}
B)while
- 常使用的格式:
初始化语句;
while(条件表达式){
循环体语句;
控制体语句/步长语句;
}
- 循环的执行流程:
1)初始化话语句进行赋值
2)条件表达式成立,
执行循环体语句
再次执行控制体语句
3)再次判断条件表达式是否成立,
…
…
当条件不成立,则while结束
应用场景:不明确循环次数的时候:使用
/*求1-100的偶数和*/
int x = 1 ;
int sum = 0 ;
while(x<=100){
if(x % 2 ==0){
sum += x ;
}
x ++;
}
- for和while循环的区别?
1)从格式上来讲:格式不同
for(初始化语句;条件表达式;控制体语句){
循环体语句;
}
初始化语句;
while(条件表达式){
循环体语句;
控制体语句;
}
for循环结束之后,不能在访问for中变量,for循环结束;
变量需要被释放掉了!
while循环可以访问
2)内存:for循环节省内存空间
堆,栈内存(存储局部变量:在方法定义中/方法声明上的变量),
方法区..(main())
for循环结束,变量随着被释放掉,节省内存空间;(不能访问这个变量了.)
while循环结束,依然可以访问这个变量,比较消耗内存空间...
3)使用场景:
for循环:明确循环次数使用 水仙花数:100-999 (开发中:优先考虑for)
while循环:不明确循环次数,使用
- 举例:
猜数字游戏:
猜数字游戏:
用户输入的数据和已经存在随机进行比较,用户不断录入数据!
一般情况:都会采用
while(true){
当达到某种条件时结束; break;(不能单独使用,只能在switch和循环)
}
分析:
1)产生一个1-100之间随机数:num
用户不断录入
while(true){ //使用最多
2)创建键盘录入对象
3)提示并录入数据, guessNumber
4)多种情况进行判断:if..else if...else
如果guessNumber > num
提示"您要猜数字大了"
如果 guessNumber<num
提示"您要猜的数字小了"
否则, 恭喜您,猜中了! ,结束死循环
}
需求:
JDK提供的一个类:java.lang.Math(不需要导包):针对数学运算操作的类
产生一个随机数?
public static double random() :产生的随机的范围:[0.0,1.0)
使用:
double d = Math.random();
System.out.println("游戏开始了...") ;
//1)产生一个1-100之间随机数
int num = (int)(Math.random()*100+1) ;
while(true){//不断录入
//2)创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入一个数据:") ;
int guessNumber = sc.nextInt() ;
//进行判断
if(guessNumber>num){
System.out.println("您要猜的数字大了...") ;
}else if(guessNumber<num){
System.out.println("您要猜的数字小了...") ;
}else{
System.out.println("恭喜您,猜中了...") ;
break ;//结束
}
}
- 死循环
两种格式:
for(;;){
循环体语句;
}
while(true){
循环体语句;
}
灵活使用死循环:在开发中使用,当前满足某个条件,跳转死循环!(结束掉/中断掉)
break; 关键字
C)do-while
- do-while的格式
初始化语句;
do{
循环体语句;
控制体语句;
}while(条件表达式) ;
- for,while,dowhile的区别?
- do-while:优先循环体语句,即使条件不成立,循环体至少执行一次!
在jdk提供的某些原码中可以看到do-while循环 - 开发中:
优先for,其次while,再次do-while
- do-while:优先循环体语句,即使条件不成立,循环体至少执行一次!
4.跳转控制语句
A)break
- break :结束中断,结束循环(不能单独使用),break在单层循环中使用
在switch和循环中使用
/*
外层循环,内存循环 : 在每一个循环的外面加上标签语句
标签名称:for(xx;xx;xx){}
break 标签语句;
*/
wc:for(int x = 0 ; x < 5 ; x ++){
nc:for(int y = 0 ; y < 6 ; y++){
//if(x == 2){
if(y==2){
//break wc ; //结束外层循环
break nc ;//跳槽内存循环
}
System.out.print("*") ;
}
System.out.println() ;
}
B)continue
- continue:继续, 在循环中使用 ,结束当前循环,立即进入下一次循环
- 代码补全:
for(int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
//在此处填写代码
}
System.out.println("java基础");
}
在控制台输出2次“java基础班” break;结束中断
在控制台输出7次“java基础班” continue:结束当前循环,立即进入下一次循环
在控制台输出13次“java基础班” System.out.println(“java基础”);
//2次
for(int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
//在此处填写代码
}
System.out.println("java基础班");
}
//7次
for(int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
//在此处填写代码
continue;
}
System.out.println("java基础班");
}
//13次
for(int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
//在此处填写代码
System.out.println("java基础班");
}
System.out.println("java基础班");
}
C)return
- return :很少单独使用,结合有具体返回值类型的方法使用!(方法?)
结束方法的;
return 是需要和方法相关的使用的,单独使用非常少
方法中: return 结果值;
13.方法
1.有具体返回值的方法
- 方法:是一段可以被重复调用的方法块,是使用{}代码块包起来,并且起一个名字(见名知意)
- Java中定义方法的格式:
- 有具体返回值类型的方法的定义
- 固定格式
- 有具体返回值类型的方法的定义
public static 返回值类型 方法名(参数类型1 变量名1,参数类型2 变量名2....){
方法中的业务逻辑代码...
return 结果;
}
- 两个明确
1)明确返回值类型
2)明确参数类型以及参数个数
- 详细介绍:
public: 访问权限足够大,公共的
static: 静态修饰符(面向对象中讲)
返回值类型:就是数据类型(目前使用的基本数据类型...)
方法名: 见名知意 (小驼峰命名法)
参数类型:第一个参数的数据类型
变量名:符合 (小驼峰命名法)
- 需求:
- 求两个数据之和----使用方法来进行操作!(没有告诉类型都是int)
- 有具体返回值类型的方法的调用:
1)单独调用(不用它)
2)输出调用:不建议:因为 直接输出,想使用这个结果值进行操作就不可以了
3)赋值调用:推荐- 返回值数据类型 变量名 = 方法名(实际参数列表) ;
//int result = sum(a,b) ; 调用
public static int sum(int a,int b){//形式参数
int result = a + b;//30+20
return result ;
}
- 输入一整数,判断它是否质数。
import java.util.Scanner;
public class text {
public static void main(String[] args){
Scanner cs=new Scanner(System.in);
System.out.print("输入一个数字:");
int n=cs.nextInt();
prime(n) ;
}
public static void prime(int n){
boolean b = true;
for(int i = 2 ; i <= Math.sqrt(n) ; i++) {
if(n % i == 0) {
b = false;
}
}
if(b) {
System.out.println(n + "是质数");
}else {
System.out.println(n + "不是质数");
}
}
}
- 方法使用中的注意事项
1)方法和方法是平级关系,不能进行嵌套: 在一个方法中定义另一个方法不允许
2)在Java中,定义方法的时候形式参数必须携带数据类型!(Java是一个强类型语言)
Javascript:弱类型语言:定义函数的,参数不需要带类型
3)调用方法的时候,传递的实际参数不需要在携带数据类型了
4)定义方法的时候: 有{括号的地方不能有分号;
2.没有具体返回值的方法
- 没有具体返回值类型的方法的定义:
1)针对某个功能代码块{} 没有具体的返回值类型,按照语法规定:必须有一个值
2)Java提供了一个关键字:代替没有具体返回值类型 void
3)固定格式:public static void 方法名(形式参数列表){}
方法体中的内容:直接输出或者进行其他操作;(不需要return语句了) - 没有具体返回值类型的方法调用呢?
1)单独调用:只能单独调用!
2)输出调用:不行
3)赋值调用:不行 - 两个明确:
1)明确返回值类型:没有具体返回值类型:使用void代替
2)明确参数类型以及参数个数 - 写一个方法,接收一个数据n,输出n*n乘法表
import java.util.Scanner;
class Text{
public static void main(String[] args){
Scanner sc = new Scanner(System.in) ;
System.out.print("请输入一个数:") ;
int n = sc.nextInt() ;
mult(n) ;
}
public static void mult(int m){
for(int i = 1 ; i <= m ; i++){
for(int j = 1 ; j <= i ; j++){
System.out.print(j + "*" + i + "=" + i*j+ "\t") ;
}
System.out.println() ;
}
}
}
3.方法的重载
- 方法重载(overload) :方法名相同,参数列表不同,与返回值无关!
参数列表不同:- 1)参数个数不同
- 2)参数类型不同
- 方法重载的目的:就是为了提高某个功能的扩展性
在有的时候:同一个方法,可以传递任何数据类型
a)public static void open(){}
b)public static void open(int a){}
c)static void open(int a,int b){}
d)public static void open(double a,int b){}
e)public static void open(int a,double b){}
f)public void open(int i,double d){}
g)public static void OPEN(){}
h)public static void open(int i,int j){}
//a,b,c,d,e,f,h是重载
4.形参问题
- 方法的形式参数问题:
- 1)如果方法的形式参数是基本数据类型,有什么特点?
- 形式参数的改变不会影响实际参数!
- 2)如果方法的形式参数是引用数据类型(数组),有什么特点?
- 如果形式参数是数组类型(除String类型外), 实际参数传递:传递数组对象 :形式参数的改变会直接影响实际参数。
- String类型:特殊的引用类型:它作为形式参数,效果和基本数据类型一致! 形式参数的改变不影响实际参数(String本质就是常量)
- 1)如果方法的形式参数是基本数据类型,有什么特点?
//看程序,写结果 :面试题
class ArgsDemo{
public static void main(String[] args){
//定义了两个变量
int a = 10 ;
int b = 20 ;
System.out.println("a:"+a+",b:"+b) ; //a:10,b:20
//定义了一个方法:没有具体返回值类型,void代替 直接输出
change(a,b) ;//10,20
System.out.println("a:"+a+",b:"+b) ;//10,20
System.out.println("---------------------------");
String str = "hello" ;
System.out.println("str:"+str) ; //"hello"
change(str) ;
System.out.println("str:"+str) ;
System.out.println("---------------------------");
//创建一个数组,静态初始化
int[] arr = {1,2,3,4,5} ; //int[] arr = new int[]{1,2,2,3,4,5} ;
System.out.println(arr[1]) ;
//重载的change方法
change(arr) ;
System.out.println(arr[1]) ;
}
//执行change方法
public static void change(int[] arr){//形式参数是引用类型:数组 (实际参数传递:传递的空间地址值)
//遍历arr数组
for(int x = 0 ; x < arr.length ; x ++){
if(arr[x] %2 == 0){
arr[x] *= 2 ;
}
}
}
//String类型作为形式参数传递(特殊的引用类型)
public static void change(String str){ //hello
System.out.println("str:"+str) ; //"hello"
str+="javaEE" ;//str = "hello"+"javaEE" ;
System.out.println("str:"+str) ; //"hellojavaEE"
}
public static void change(int a,int b){//形式参数是基本数据类型 10,20
System.out.println("a:"+a+",b:"+b) ;//a:10,b:20
a = b ;
b = a+ b;
System.out.println("a:"+a+",b:"+b) ;
}
}
14.数组
1.数组的定义
- 数组:就是存储多个数据的容器,必须保证容器中的数据类型一致!
- 容器:就是存储数据的"工具"
- 数组:(最基本的容器)
StringBuffer:字符串缓冲区 ---->数据 ---->String:字符串类型
集合:Collection,Map集合中
IO:存储在文件中
数据库(最终目的):存储数据的仓库
- 数组:(最基本的容器)
- 数组的定义格式:
- 动态初始化
- 静态初始化
2.动态初始化
给定了数组的长度,系统默认对元素进行初始化!
据类型[] 数组名称 = new 数据类型[数组长度] ;
数据类型 数组名称[] = new 数据类型[数组长度] ;
举例:
int[] arr ;定义一个int类型的数组arr
int[] arr = new int[3] ;
int arr[];定义了一个int类型的arr数组
int arr[] = new int[3] ;
如何访问数组元素呢:
通过数组名称[角标值]: 角标从0
数组:引用数据类型
Java内存的分配:
//创建一个数组:动态初始化 给定3个长度
int[] arr = new int[3] ;
System.out.println(arr) ;
arr = new int[2] ;
//[I@6d06d69c 地址值
//[:表示一维数组
//I:int类型数据
//@:地址标记
//6d06d69c:十六进制数据....
//默认初始化:
System.out.println(arr[0]) ;//0
System.out.println(arr[1]) ;//0
System.out.println(arr[2]) ;//0
//显示初始化了
arr[0] = 10 ;
arr[1] = 20 ;
System.out.println(arr[0]) ;//10
System.out.println(arr[1]) ;//20
System.out.println(arr[2]) ;//0
- 内存分配:
- 寄存器:程序无法控制(和计算机cpu有关系)
- 栈:存储都是局部变量(在方法定义中或者方法声明上)
- 堆:new出来的东西,创建对象 (里面存储:“成员变量”)
- 方法区:有哪些方法–分别存储在哪个类中—xxx.class()
- 字节码文件区:class:存储字节码文件对象
- 静态区:static : 以后: 存储的静态成员 (在面向对象中讲)
- 常量池 :String “字符串就是一个常量” (在常用类中)
/*创建两个数组,分别输出对象名称,以及元素内容(数组对象[角标值])
分别给两个数组中的部分元素赋值(显示初始化),
再次输出两个数组对象名称以及元素内容*/
class ArrayDemo2{
public static void main(String[] args){
//动态初始化
//创建第一个数组对象
int[] arr = new int[2] ;//2个长度(角标:0,1)
//创建第二个数组对象
int[] arr2 = new int[3] ;//3个长度(角标0,1,2)
System.out.println(arr) ;
System.out.println(arr2) ;
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
System.out.println(arr2[0]) ;
System.out.println(arr2[1]) ;
System.out.println(arr2[2]) ;
System.out.println("--------------------------------") ;
//给部分元素内容赋值
arr[1] = 100 ;
arr2[0] = 50 ;
arr2[2] = 30 ;
System.out.println(arr) ;
System.out.println(arr2) ;
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
System.out.println(arr2[0]) ;
System.out.println(arr2[1]) ;
System.out.println(arr2[2]) ;
System.out.println("-----------------------") ;
arr2 = new int[2] ;
System.out.println(arr2) ;
}
}
/*
先创建两个数组对象(动态初始化),输出对象名称以及元素内容(显示初始化)
定义第三个数组:将第一个数组对象地址值赋值给第三个数组名称
通过第三个数组名称 arr3[角标值] = 赋值;
再次输出前两个数组对象名称以及内容
*/
class ArrayDemo3{
public static void main(String[] args){
//创建两个数组对象:动态初始化
int[] arr = new int[3] ;
int[] arr2 = new int[2] ;
System.out.println(arr) ;
System.out.println(arr2) ;
arr[0] = 100 ;
arr[1] = 30 ;
arr[2] = 20 ;
arr2[1] = 10 ;
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
System.out.println(arr[2]) ;
System.out.println(arr2[0]) ;
System.out.println(arr2[1]) ;
System.out.println("-----------------") ;
//定义第三个数组,将第一个数组的对象名称赋值给他
int[] arr3 = arr ;
arr3[0] = 50;
arr3[2] = 40 ;
System.out.println(arr) ;
System.out.println(arr2) ;
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
System.out.println(arr[2]) ;
System.out.println(arr2[0]) ;
System.out.println(arr2[1]) ;
}
}
3.静态初始化
静态初始化:我们给定的具体的元素,数组长度由系统确定
静态初始化的格式:
数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,元素3....} ;
数据类型 数组名称[] = new 数据类型[]{元素1,元素2,元素3....} ;
简化格式:
数据类型[] 数组名称 = {元素1,元素2,元素3....} ;
数据类型 数组名称[] = {元素1,元素2,元素3....} ;
举例:
int[] arr = {5,6,7,8} ;
//错误的写法:动静结合!(只能有一种初始化方式:不能既是动态初始化,也是静态初始化)
int[] arr = new int[3]{1,2,3} ;
class ArrayDemo4{
public static void main(String[] args){
//创建一个数组,静态初始化
int[] arr = {11,22,33,44,55} ;
//等价于 int[] arr = new int[]{11,22,33,44,55} ;
System.out.println(arr) ;
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
System.out.println(arr[4]) ;
//System.out.println(arr[5]) ;//编译通过:数组对象[角标值]:语法正确的!
//引用类型的默认值null
arr = null ;
if(arr!=null){
System.out.println(arr[0]) ; //再访问
}else{
System.out.println("数组对象为空了,访问不了...");
}
}
}
程序异常
程序出现异常了 :
编译时期异常:jvm运行java程序:检查语法 (调用者必须处理!)
后期:IOEXception: 读写数据时
ParseExceptin:解析异常
将"2021-7-13" 日期文本格式---->java.util.Date
运行时期异常:
RuntimeException
代码逻辑不严谨或者其他业务判断导致的出现问题
ArrayIndexOutOfBoundsException:
数组角标越界异常
开发者:需要检查数组的角标是否正确!
NullpointerException:空指针异常:
描述:当前某个对象为null,我们还要使用对象操作,就会出现问题了
都是可以通过逻辑判断解决
针对某个对象进行非空判断
数组经典题
1)数组遍历
/*
将数组的遍历,定义成一个方法
两个明确:
1)明确返回值类型:void 没有具体返回值
2)明确参数类型以及参数个数
int[] arr,1个
*/
//最终版代码:定义一个方法:[元素1, 元素2, 元素3, 元素n]输出结果
public static void printArray2(int[] arr){ //形式参数并非基本数据类型,而是引用数据类型
//先输出一个左中括号 ,输出时不换行
System.out.print("[") ;
//遍历数组
//元素很多:不能数了,通过 数组具备有属性 length:获取数组长度
for(int x = 0 ; x < arr.length ; x ++){
//判断:如果当前x :取到最大索引值 arr.length-1
if(x==arr.length-1){
System.out.println(arr[x]+"]") ;
}else{
//不是最后一个索引值,中间的元素 arr[x]+", " 不换行
System.out.print(arr[x]+", ") ;
}
}
}
2)数组的逆序
public class test {
//便利数组
public static void printArray(int arr[]) {
System.out.print("[");
for(int i = 0 ; i < arr.length ; i++) {
if(i == arr.length-1) {
System.out.println(arr[i] + "]");
}else {
System.out.print(arr[i] + ", ");
}
}
}
//是数组逆序
public static void reverse(int arr[]) {
for(int i = 0 ; i < arr.length/2 ; i++ ) {
int temp = arr[i] ;
arr[i] = arr[arr.length-1-i] ;
arr[arr.length-1-i] = temp ;
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6} ;
System.out.println("逆序之前的数组:");
printArray(arr);
System.out.println("逆序之后的数组:");
reverse(arr);
printArray(arr);
}
}
3)查询n这个元素第一次在数组arr中出现的索引
import java.util.Scanner;
public class test {
public static int search(int[] arr , int n) {
int index = -1 ;
for(int i = 0 ; i < arr.length ; i++) {
if(arr[i] == n) {
index = i ;
}
}
return index;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in) ;
System.out.print("请您输入一个数据:");
int n = sc.nextInt() ;
int[] arr = {1,2,3,4,5} ;
int i = search(arr, n) ;
System.out.printf("%d在数组中第一次出现的下标是:%d",n,i);
}
}
4)给定一个数组,输出数组中的最大值和最小值(键盘录入一个数组,5个元素)
import java.util.Scanner;
public class text {
public static void main(String[] args){
Scanner sc = new Scanner(System.in) ;
System.out.println("请输入一个数组:") ;
int[] arr = new int[5] ;
for(int i = 0 ; i <= 4 ;i++) {
System.out.printf("请输入第%d个数:",i+1) ;
arr[i] = sc.nextInt() ;
}
maxAndMix(arr);
}
public static void maxAndMix(int[] arr) {
int max = arr[0];
int min = arr[0];
for(int i = 0 ; i < arr.length ; i++) {
if(max < arr[i]) {
max = arr[i] ;
}
if(min > arr[i]) {
min = arr[i] ;
}
}
System.out.println("数组中的最大值为:" + max);
System.out.println("数组中的最小值为:" + min);
}
}
4.数组的排序
1.冒泡排序
//冒泡排序
/*
两两比较,较大的值往后放,第一次比较完毕,最大值出现在最大索引处
依次这样比较,可以得到排好序的数组!
*/
public class bubbleSort {
public static void main(String[] args){
int[] arr = {8,7,6,5,4,3,2,1,0} ;
System.out.println("排序前:");
printArray(arr);
System.out.println("冒泡排序后:");
Sort(arr);
printArray(arr);
}
public static void printArray(int[] arr) {
System.out.print("[");
for(int i = 0 ; i < arr.length ;i++) {
if(i == arr.length-1) {
System.out.println(arr[i] + "]");
}else {
System.out.print(arr[i] + ", ");
}
}
}
public static void Sort(int[] arr) {
for(int i = 0 ; i < arr.length-1 ; i ++) { //外层:比较的次数
for(int j = 0 ; j < arr.length-1-i ;j ++) { //内层循环:进行比较互换
if(arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1] ;
arr[j+1] = temp ;
}
}
}
}
}
2.选择排序
//选择排序
public class selectionSort {
public static void main(String[] args) {
int[] arr = {8,7,6,5,4,3,2,1,0} ;
System.out.println("排序前:");
printArray(arr);
System.out.println("排序后:");
selection(arr);
printArray(arr);
}
public static void printArray(int[] arr) {
System.out.print("[");
for(int i = 0 ; i < arr.length ;i++) {
if(i == arr.length-1) {
System.out.println(arr[i] + "]");
}else {
System.out.print(arr[i] + ", ");
}
}
}
public static void selection(int[] arr) {
for(int i = 0 ; i < arr.length-1 ; i++) {
int Index = i ;//记录最小索引
for(int j = i+1 ; j < arr.length ; j++) {
if(arr[i] > arr[j]) {
Index = j ;
}
}
//i不是最小时,将i和最小数进行交换
if(i != Index) {
int swap = arr[Index] ;
arr[Index] = arr[i] ;
arr[i] = swap ;
}
}
}
}
3.插入排序
//插入排序
public class insertionSort {
public static void main(String[] args) {
int[] arr = {8,7,6,5,4,3,2,1,0} ;
System.out.println("排序前:");
printArray(arr);
System.out.println("排序后:");
insertion(arr);
printArray(arr);
}
public static void insertion(int[] arr) {
int current ;
int Index ;
for(int i = 1 ; i < arr.length ; i ++) {
current = arr[i] ;
Index = i - 1 ;
while(Index >= 0 && current < arr[Index] ) {
arr[Index+1] = arr[Index] ;
Index-- ;
}
arr[Index+1] = current ;
}
}
public static void printArray(int[] arr) {
System.out.print("[");
for(int i = 0 ; i < arr.length ;i++) {
if(i == arr.length-1) {
System.out.println(arr[i] + "]");
}else {
System.out.print(arr[i] + ", ");
}
}
}
}
15.面向对象
1.面向对象
- 面向对象基于面向过程:
- 面向过程: (自己就是执行者) 代表:c语言
- 需求分析
- 定义功能代码块(方法)
- 在main 方法调用,显示结果
- 面向对象:代表java语言
需要找一个对象完成一件事件:比如 :键盘录入一个数据 (jdk提供—>Scanner)
创建键盘录入对象
提示并录入数据
展示结果 - 特点:
- 是一种更符合我们思想习惯的思想
- 可以将复杂的事情简单化
- 将我们从执行者变成了指挥者
角色发生了转换
- 面向过程: (自己就是执行者) 代表:c语言
生活中的例子:
面向过程:
买电脑:
看自己的需求配置--->自己去赛格电脑城---->对比几家:砍价还价---->买到电脑
洗衣服:
脱下脏衣服--->泡一泡---->搓一搓--->拧一拧---->晾一晾
买菜做饭:
去菜市场--->砍价--->摘菜--->洗菜---->切菜--->起锅烧油--->炒菜--->出锅
面向对象:
买电脑:
找一个懂行的朋友(对象)---->只要去赛格买电脑(谈价格)---->给我买回来
洗衣服:
脱下脏衣服---->放在全自动洗衣机(一键)---->晾一晾
买菜做饭:
找一个对象--->等待出锅
面向对象:"万物皆对象"
面向对象是什么? 举生活中例子,再答上思想特点。
面向对象的思想特点:
1)更符号我们生活中是思想行为习惯
2)让复杂的事情简单化
3)我们从执行者变成了指挥者
"将大象装进冰箱"
分别使用面向过程和面向对象的方式去解决:
伪代码
面向过程:
测试类:Demo
class Demo{
public static void main(String[] args){
//打开冰箱门的方法
open();
//将大象装进去
in();
//关闭冰箱门
close() ;
}
//定义一个:打开冰箱的方法
public static void open(){
System.out.println("打开冰箱门") ;
}
//定义一个方法:将大象装进去的方法
public static void in(){
System.out.println("将大象装进去") ;
}
//定义一个关闭冰箱门的方法
public static void close(){
System.out.println("关闭冰箱门")
}
}
面向对象:
"将大象装进冰箱"
UML语言:名词提前法
将大象--->大象类 (类:java语言中的最基本的单元)
有进去的方法
冰箱---->冰箱类
开和关的功能
测试类:Demo
main():程序入口
//测试类
class Demo{
public static void main(String[] args){
创建冰箱类对象
冰箱类对象.open() ;
创建出大象类对象
大象类对象.in() ;
冰箱类对象.close() ;
}
}
//定义一个大象类
class 大象类{
//应该定义一个功能:大象有进去的功能
public void in(){ //将static去掉
System.out.println("大象进去了...") ;
}
}
//冰箱类
class 冰箱类{
//开
public void open(){
System.out.println("开冰箱门") ;
}
//关
public void close(){
System.out.println("关冰箱门") ;
}
}
代码量比之前大了,但是结构层次清晰:
某个类中有功能!
面向对象的三大特征:
封装,继承,多态! (以后围绕这个东西完成一些需求!)
面向对象的设计理念:
不断的去创建对象,使用对象,指挥对象做事情! (Scanner:键盘录入)
2.类与对象
- 类:能够描述现实世界真实事物的一组属性和行为的集合!
- 对象:客观存在的具体实物。
- 事物: 现实真实存在的事物!
人—>事物
电脑—>事物
…
事物:
属性 (能够描述现实世界事物的特征)
学生事物:
姓名,性别,年龄,身高,学号
行为:这个事物的能做什么
学生事物:
吃,睡,学java,玩游戏...
通过java语言将现实世界事物的属性和行为表示出来(用程序的方式写出来)
java中类:是最基本的单元
学生事物(概括) 代码 ---- 定义 "学生类" class Student
属性:姓名,性别,年龄 "成员变量":位置:是类中,方法外
name,gender/sex,age
行为:吃,睡,学习 "成员方法":
之前的方法怎么定义,现在还怎么定义
(去掉了static)
具体的学生事物 创建对象: 格式:类名 对象名 = new 类名();
只要当在描述"张三","男",20 对象名.name = "张三" ;
"李四","女",22 对象名.age = 20 ;
对象名.sex = "男" ;
测试(1)
/*
描述一个学生事物:
属性:姓名,年龄,性别,学号
行为:吃,睡,学习
分析:
1)需要使用代码描述学生事物----->定义一个类 :学生类
2)类中定义成员变量:描述学生事物的属性
成员变量:类中,方法外定义
3)描述行为----->在学生类中定义为"成员方法" 去掉了static
4)在StuentDemo类中进行测试
*/
//定义一个学生类:描述学生事物
class Student{
//定义成员变量:描述学生事物属性的:属性:姓名,年龄,性别,学号
String name ; //姓名
int age ; //年龄
String sex ; //性别
String id; //学号
//定义成员方法:描述学生事物的行为:吃,睡,学习 (去掉了static)
public void eat(){
System.out.println("学习饿了,就需要吃饭...") ;
}
//睡
public String sleep(){
return "学习困了,就需要休息" ;
}
//学习
public void study(String className){
System.out.println("正在学习"+className) ;
}
}
//测试类
class StuentDemo{
public static void main(String[] args){
//上面的学生Student:只是描述学生事物----具体的学生是谁? "高圆圆",42,"女","9527"
//具体的学生事物---代码中---->创建对象
//类名 对象名 = new 类名() ;
Student student = new Student() ;
//使用对象名.成员变量名 = 赋值; (判定类型)
student.name = "高圆圆" ;
student.age = 42;
student.sex = "女" ;
student.id = "9527" ;
//输出结果:显示描述的具体学生事物的属性信息
System.out.println("学生的姓名是"+student.name+",年龄是:"+student.age+",性别是:"+student.sex+
",学号是:"+student.id) ;
//测试学生事物的行为:
//对象名.成员方法名(xx) ;
student.eat() ;
String msg = student.sleep() ;
System.out.println(msg) ;
//学习
student.study("JavaEE") ;
}
}
1)类的定义
测试(2)
/*
手机事物-----使用面向对象的方式: 定义手机类
品牌,价格,颜色,内存的属性
打电话,发短信,玩游戏,学习的行为
*/
class Phone{
//成员变量
String brand ; //品牌
int price ; //价格
String color ;//颜色
int memory ; //内存
//成员方法
public void callPhone(String toName){ //参数toName:给谁打电话
System.out.println("给"+toName+"打电话") ;
}
public void sendMsg(){
System.out.println("可以使用手机发短信...") ;
}
public String playGame(String gameName){
return "可以玩"+gameName+"游戏" ;
}
public void study(String className){
System.out.println("学习"+className) ;
}
}
//手机类的测试类
class PhoneTest{
public static void main(String[] args){
//测试手机类
//类名 对象名 = new 类名() ;
Phone phone = new Phone() ;
System.out.println(phone) ;
System.out.println("当前手机的品牌是:"+phone.brand+",价格是:"+phone.price+",手机颜色:"+phone.color+
",手机内存是:"+phone.memory+"G");
System.out.println("---------------------") ;
//访问成员变量
phone.brand = "华为mate30pro" ;
phone.price = 6999 ;
phone.color = "粉翠绿" ;
phone.memory = 64;
System.out.println("当前手机的品牌是:"+phone.brand+",价格是:"+phone.price+",手机颜色:"+phone.color+
",手机内存是:"+phone.memory+"G");
System.out.println("-----------------------------") ;
//访问成员方法
phone.callPhone("高圆圆") ;
phone.sendMsg() ;
String result = phone.playGame("csgo") ;
System.out.println(result) ;
phone.study("JavaEE") ;
}
}
class PhoneTest2{
public static void main(String[] args){
//创建两个手机类对象
Phone p1 = new Phone() ;
Phone p2 = new Phone();
System.out.println(p1) ;
System.out.println(p2) ;
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color+"---"+p1.memory) ;
System.out.println(p2.brand+"---"+p2.price+"---"+p2.color+"---"+p2.memory) ;
//赋值
p1.brand = "iphone12" ;
p1.price = 5999 ;
p1.color = "玫瑰金" ;
p1.memory=64 ;
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color+"---"+p1.memory) ;
System.out.println("-----------------------------") ;
p2.brand = "锤子手机" ;
p2.price = 2999 ;
p2.color = "天空灰" ;
p2.memory= 32 ;
System.out.println(p2.brand+"---"+p2.price+"---"+p2.color+"---"+p2.memory) ;
//成员方法p1.方法名() ;
// p2.方法名() ;
}
}
class PhoneTest3{
public static void main(String[] args){
//创建两个手机类对象
//定义第三个Phone类型的变量 p3
//将第一个手机类对象赋值给p3变量
//再次通过p3.访问成员变量 ="赋值"
//输出:第一个手机类对象中的所有属性
Phone p1 = new Phone() ;
p1.brand = "小米11" ;
p1.price = 3999 ;
p1.color = "黑色";
p1.memory = 128;
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color+"---"+p1.memory) ;
Phone p2 = new Phone() ;
p2.brand = "华为mate40保时捷版" ;
p2.price = 12999;
p2.color = "天空之境";
p2.memory = 128 ;
System.out.println(p2.brand+"---"+p2.price+"---"+p2.color+"---"+p2.memory) ;
//定义第三个Phone类型的变量 p3
Phone p3 = p1 ;
p3.brand = "iphone11" ;
p3.price = 1299 ;
p3.color ="土豪金" ;
p3.memory = 64 ;
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color+"---"+p1.memory) ;
}
}
形参问题
- 如果一个方法的形式参数是引用类型是具体类,那么调用该方法时,实际参数如何传递?
/*
需求:访问Demo类中的show方法?
*/
//程序类
class Programmer{
public void coding(){
System.out.println("程序员根据需求写代码...") ;
}
}
//定义Demo类
class Demo{
//有一个成员方法
public void show(Programmer programmer){//如果方法的形式参数是一个引用类型:类---就需要创建当前类对象
programmer.coding() ;
}
}
class Test{//测试类
public static void main(String[] args){
//创建Demo类对象
Demo d = new Demo() ;
//创建Programmer类的对象
Programmer pro = new Programmer() ;
d.show(pro) ;
}
}
2)成员变量和局部变量
- 成员变量和局部变量的区别?
- 在程序中的书写位置不同
局部变量: 方法定义中或者方法声明上
成员变量: 在类中,成员方法外定义的变量 - 在内存中
局部变量: 在栈内存中
成员变量: 在堆内存中 - 生命周期不同
局部变量: 随着方法调用而存在,随着方法调用完毕而消失!
成员变量: 随着对象的创建而存在,随着对象创建完毕之后,不会立即消失,需要等待GC(垃圾回收器空闲时候回收掉!)
GC算法----->标记算法
标记—清除 - 初始化不同
局部变量: 可以先定义,但是必须在使用之前必须赋值,否则:可能尚未初始化变量
成员变量: 可以不初始化,它存在系统默认初始化!(根据类型判定)
//定义一个类:Variable
class Variable{
//类中,方法外定义的变量
int x ;
//定义一个成员方法
public void method(int a){//局部变量
int b =100; //局部变量
System.out.println("method Variable..."+a) ;
System.out.println(b) ;
}
}
//测试类
class VariableDemo{
public static void main(String[] args){
//访问x变量
//创建Variable类的对象
Variable var = new Variable() ;
System.out.println(var.x) ;
var.x = 100 ;
System.out.println(var.x) ;
System.out.println("----------------") ;
//需求:访问Variable类中的method 方法?
var.method(10) ;
}
}
3)匿名对象
- 匿名对象:.顾名知意:没有 名字的对象
- 格式: new 类名() ;
- 匿名对象有一个特点:可以作为参数进行传递
在开发中,匿名对象使用一次即可!
(因为没有栈内存变量指向堆内存地址,直接是在堆内存开辟空间,使用完毕,立即被回收!) - 场景:
在android 应用中:匿名对象使用很多 节省内存空间
手机app:手机内存比较小的
//定义学生类
class Student{
public void study(){
System.out.println("爱生活,爱Java,爱敲代码...") ;
}
}
//定义StudentDemo类
class StudentDemo{
public void method(Student student){
student.study() ;
}
}
//测试类
class NoNameObjectDemo{
public static void main(String[] args){
//之前的写法
//访问StudentDemo类中的method 方法
//创建StudentDemo类对象
StudentDemo sd = new StudentDemo() ;
//创建一个具体的学生对象
Student s = new Student() ;
sd.method(s) ;
System.out.println("------------------------------") ;
//方式2
StudentDemo sd2 = new StudentDemo() ;
sd2.method(new Student()) ;
System.out.println("------------------------------") ;
//链式编程
//一步走
new StudentDemo().method(new Student()) ;
}
}
3.封装
- 封装:为了将某个类的成员属性隐藏(将属性(成员变量)“私有化”),并为之提供公共(public)访问方式!(setXXX()/getXXX())
- 私有化:就是关键字"private" 只能在本类中访问
- 封装目的:为了保证的数据的安全性!
- private关键字的特点:
1)可以修饰成员变量,也可以修饰成员方法,但是都只能在本类访问,外界类不能够访问
2)这些被私有修饰的成员变量,或者成员方法,可以间接通过公共方法来访问!
//Demo类
class Demo{
//私有的成员变量
private int num = 100 ;
public int num2 = 200 ;
//定义私有的成员方法
private void method(){
System.out.println("method demo...") ;
}
//定义一个公共方法
public void show(){
System.out.println(num) ;
}
//公共方法
public void function(){
method() ;
}
}
//测试类
class PrivateDemo{
public static void main(String[] args){
//访问Demo类中的num2变量?
Demo d = new Demo() ;
System.out.println(d.num2) ;
//System.out.println(d.num) ; //num 在 Demo 中是 private 访问控制
d.show() ;
System.out.println("-----------------------") ;
//要访问Demo类中method方法
//d.method() ;//method() 在 Demo 中是 private 访问控制
d.function() ;
}
}
给学生类中的成员加入私有修饰,对外提供公共的方法(setXXX()/getXXX())
学生事物:
姓名,年龄,性别,爱好的属性
学习,玩游戏,运动的行为
定义一个学生描述学生事物并在StudentTest2中测试
class Student2{
//成员变量私有化
private String name ;//姓名
private int age ; //年龄
private String gender ;//性别
private String hobit ; //爱好
//成员方法
public void study(){
System.out.println("学习JavaEE...") ;
}
//玩游戏
public String playGame(String gameName){
return "会玩"+gameName ;
}
//运行
public void sport(){
System.out.println("喜欢踢足球...") ;
}
//一些公共访问方法:给姓名,年龄,性别,爱好赋值 /还需要获取这些内容
//给学生的姓名赋值
public void setName(String n){ //"高圆圆"
name = n ; //name = n = "高圆圆"
}
//获取学生的姓名--->返回值:String
public String getName(){
return name ;
}
//给学生的年龄赋值
public void setAge(int a){ //41
age = a ; //age = a = 41
}
//获取学生的年龄:int类型
public int getAge(){
return age ;
}
//给学生的性别赋值
public void setGender(String g){ //"女"
gender = g ; //gender = g ="女"
}
//获取学生的性别:String
public String getGender(){
return gender ;
}
//给学生的爱好赋值
public void setHobit(String h){ //"跑步"
hobit = h ; //hobit = h = "跑步"
}
//获取学生的爱好:String
public String getHobit(){
return hobit ;
}
}
//测试类
class StudentTest2{
public static void main(String[] args){
//创建学生类测试
Student2 s = new Student2() ;
//对象名.公共的成员方法名() 赋值
s.setName("高圆圆") ;
s.setAge(41) ;
s.setGender("女") ;
s.setHobit("跑步") ;
System.out.println("当前学生的姓名是:"+
s.getName()+",年龄是:"+s.getAge()+",性别是:"+s.getGender()+",爱好是:"+s.getHobit()) ;
//其他成员方法
s.study() ;//学习
String str = s.playGame("lol") ;
System.out.println(str) ;
s.sport() ;
}
}
4.this关键字
- 关键字this:解决局部变量隐藏了成员变量
this.成员变量名 = 局部变量;
this:就是代表当前类的对象的地址值引用!
/*
学生事物
属性:姓名,年龄,性别
行为:学习,抽烟...
学生类进行描述学生事物---加入封装思想并加入this关键字
*/
//定义一个学生类
class Student{
private String name ;
private int age ;
private String gender ;
//提供公共 的setXXX()/getXXX()方法
//赋值姓名
public void setName(String name){
this.name = name ;
}
public String getName(){
return name ;
}
//给年龄赋值
public void setAge(int age){
this.age = age ;
}
//获取年龄
public int getAge(){
return age ;
}
//给性别赋值
public void setGender(String gender){
this.gender = gender ;
}
//获取性别
public String getGender(){
return gender ;
}
//学生学习的成员方法
public void study(String className){
System.out.println("正在学习"+className) ;
}
//抽烟
public void smoke(String smokeBrand){
System.out.println("抽"+smokeBrand) ;
}
}
//测试类
class StudentTest{
public static void main(String[] args){
//创建学生类对象
Student s = new Student() ;
//赋值setXXX
s.setName("马三奇") ;
s.setAge(20) ;
s.setGender("男") ;
System.out.println("学生的姓名是:"+s.getName()+",年龄为:"+s.getAge()+",性别为:"+s.getGender()) ;
s.study("JavaSE之面向对象") ;
s.smoke("小橘") ;
}
}
Student s = new Student() ;完成了那些事?
5.构造方法
- 构造方法:
1)构造方法名和类名一致
2)没有具体的返回值类型
3)连void都没有 - 构造方法的目的:为了给类的成员的一些数据进行初始化
//定义一个学生类
class Student{
private String name ;//姓名
private int age ; //年龄
//定义一个构造方法?
//无参构造方法
public Student(){
System.out.println("这是Student类的无参构造方法...") ;
}
//定义有参构造方法(带一个String类型的参数)
public Student(String name){//局部变量 "高圆圆"
//this.name = name ;
System.out.println("这是Student类带String类型的有参构造方法...") ;
}
//带一个int类型的有参构造
public Student(int age){
System.out.println("这是Student类带int类型的有参构造方法...") ;
}
//带两个参数的有参构造
public Student(String name,int age){
System.out.println("这是Student类带两个参数的有参构造方法...") ;
}
}
//测试类
class ConstructorDemo{
public static void main(String[] args){
//创建学生类对象
Student s = new Student() ;
System.out.println("------------------") ;
Student s2 = new Student("高圆圆") ;
System.out.println("------------------") ;
Student s3 = new Student(41) ;
System.out.println("------------------") ;
Student s4 = new Student("高圆圆",41) ;
}
}
- 构造方法的使用注意事项:
1)当我们书写某个类中代码的时候,没有给这个类提供任何构造方法,那么系统会默认提供一个无参构造方法
2)如果我们提供了有参构造方法任何一种,那么系统就不会在无参构造方法了
建议:永远给出类的无参构造方法
构造方法的目的:就是为类的成员进行数据初始化!
给成员变量赋值有几种?
两种:
提供的公共的访问方法:sexXXX()
构造方法
加入构造方法之后,一个标准类的写法
/*
学生类
属性:私有化 姓名,年龄,性别,学号
行为:吃,睡,学习
公共访问方法setXXX()/getXXX()
构造方法:
无参构造方法/有参构造方法
*/
//手机类
class Phone{
private String brand ;
private int price ;//价格
private String color ;
public Phone(){
}
//提供了带参数构造方法
//("锤子手机",1299,"黑色"
public Phone(String brand,int price ,String color){//局部变量
this.brand = brand ;
this.price = price ;
this.color = color ;
}
//提供setXXX()/getXXX()方法
public void setBrand(String brand){
this.brand = brand ;
}
public String getBrand(){
return brand ;
}
//给价格赋值
public void setPrice(int price){
this.price = price ;
}
public int getPrice(){
return price ;
}
//给颜色赋值
public void setColor(String color){
this.color = color ;
}
public String getColor(){
return color ;
}
//其他成员方法(手机事物的行为)
}
//测试类
class ConstructorDemo2{
public static void main(String[] args){
//通过无参构造方法创建对象
//方式1:无参构造方法+setXXX()/getXXX()
Phone p = new Phone();//
//setXXX()赋值
p.setBrand("锤子手机") ;
p.setPrice(1299) ;
p.setColor("黑色") ;
System.out.println("品牌:"+p.getBrand()+",价格:"+p.getPrice()+",颜色:"+p.getColor()) ;
System.out.println(p) ;
System.out.println("---------------------") ;
//方式2:通过有参构造方法赋值 + 结合getXXX()获取内容
Phone p2 = new Phone("锤子手机",1299,"黑色") ;
System.out.println("品牌:"+p2.getBrand()+",价格:"+p2.getPrice()+",颜色:"+p2.getColor()) ;
}
}