Java Study Notes_Design in 2023(Day01~Day14)
文章目录
- Day01:Java入门
- 1.1 Java的技术体系
- 1.2 Java快速入门
- 1.2.1 JDK、JRE与JVM
- 1.2.2 JDK环境变量配置
- 1.3 Java基础语法
- 1.3.1 注释
- 1.3.2 字面量
- 1.3.3 JAVA关键字
- 1.3.4 标志符
- 1.3.5 变量
- Day02: 数据类型、运算符
- 2.1 数据的表示详解
- 2.1.1二进制
- 2.2 数据的表示
- 2.2.1 进制转换
- 2.2.3 字符在计算机中的存储原理
- 2.2 数据类型
- 2.3 类型转换
- 2.3.1 自动类型转换
- 2.3.2 强制类型转换
- 2.4 运算符
- 2.4.1 算术运算符
- 2.4.2 自增自减运算符
- 2.4.3 赋值运算符
- 2.4.4 关系运算符
- 2.4.5 逻辑运算符
- 2.4.6 三元运算符
- 2.4.7 运算优先级
- 2.5 案例技术:获取用户键盘输入的数据
- Day03: 程序流程控制
- 3.1 选择结构
- 3.1.1 if单选择结构
- 3.1.2 if双选择结构
- 3.1.3 多单选择结构
- 3.1.4 嵌套if结构
- 3.1.5 switch多选择结构
- 3.1.6 jdk7新特性
- 3.2 循环结构
- 3.2.1 while循环
- 3.2.2 do...while循环
- 3.2.3 For循环
- 3.2.4 增强for循环
- 3.3 练习
- 3.3.1 练习1:计算0到100间的奇数和偶数的和
- 3.3.2 练习2:用while或for循环输出1~1000间能被5整除的数,并且每行输出3个
- 3.3.3 练习3:输出9X9乘法表
- 3.4 break和continue关键字
- 3.5 随机数
- 3.5.1 产生一个随机数
- 3.5.2 猜数字小游戏
- Day04: Java数组
- 4.1 认识数组
- 4.2 数组的定义和访问
- 4.2.1静态初始化
- 4.2.2 数组的动态初始化
- 4.3 内存分析
- 4.4 数组在计算机中的执行原理
- 4.5 多个变量指向同一个数组的问题
- 4.6 数组练习
- 4.6.1 数组求最值
- 4.6.2 数组存取用户数据进行随机排名
- 4.6.3 冒泡排序
- 4.6.4 数组元素反转
- 4.7 Debug调试
- Day05: 方法
- 5.1 方法概述
- 5.2 方法的定义
- 5.3 方法在计算机中的执行原理
- 5.3.1 有返回值的方法,内存分析
- 5.3.2 无返回值的方法,内存分析
- 5.4 方法参数的传递机制
- 5.4.1 方法参数传递是基本类型数据,内存执行原理
- 5.4.2 参数是引用类型,实际上也是值传递,只不过参数传递存储的地址值
- 5.4.3 方法参数传递案例1
- 5.5 方法重载
- 5.5.1 方法重载案例一
- 5.5.2 方法重载案例二
- 5.6 return单独使用
- Day06: Java编程案例思维训练
- 6.1 完成买飞机票的案例
- 6.2 完成生成随机验证码
- Day07:Java面向对象基础
- 7.1 对象在计算机中的执行原理
- 7.2 类和对象的一些注意事项
- 7.3 this关键字
- 7.4 构造器
- 7.5 封装性
- 7.6 实体JavaBean
- 7.6.1 实体类案例一
- 7.6.2 面向对象综合案例
- 7.7 成员变量和局部变量的区别
- Day08: Java常用API
- 8.1 String类
- 8.2 ArrayList类
- Day09: Java基础项目(ATM系统)
- Day10:面向对象高级
- 10.1 "static" 关键字
- 10.1.1 static修饰成员变量
- 10.1.2 内存原理
- 10.1.3 static修饰成员方法
- 10.1.4 内存分析
- 10.1.5 static的注意事项
- 10.2 代码块(匿名、静态)
- 10.2 单例设计模式
- 10.2.1 单例设计模式之饿汉式
- 10.2.2 单例设计模式之懒汉式
- Day11: 面向对象高级二
- 11.1 多态
- 11.2 多态优点
- 11.2.1 案例一
- 11.3 final关键字
- 11.3.1 案例一
- 11.3.2 案例二
- 11.3.3 案例二
- 11.4 抽象类
- 11.4.1 案例一
- 11.4.2 案例二
- 11.4.3 案例三
- 11.5 设计模式——模板方法模式
- 11.6 接口
- 11.6.1 案例一
- 11.6.2 案例二
- Day12: 面向对象高级三
- 12.1 内部类
- 12.1.1 成员内部类
- 12.2.2 静态内部类
- 12.2.3 局部内部类
- 12.2.4 匿名内部类
- 12.3 枚举
- 12.4 泛型
- 12.5 常用API
- 12.5.1 Object类
- 12.5.2 基本类型包装类
- Day13: 常用API
- 13.1 StringBuilder与StringBuffer类
- 13.2 Math类
- 13.3 System类
- 13.4 Runtime类
- 13.5 BigDecimal类
- 13.6 Date类
- 13.7 SimpleDateFormat类
- 13.8 Calendar类
- 13.9 JDK8日期、时间、日期时间
- 13.9.1 LocalDate类
- 13.9.2 LocalTime类
- 13.9.3 LocalDateTime类
- 13.10 JDK8日期(时区)
- 13.11 JDK8日期(Instant类)
- 13.12 JDK8日期(格式化器DateTimeFormater)
- 13.13 JDK8日期(Period类和Duration类)
- 13.14 Arrays类
- 13.14 .1 Arrays基本使用
- 13.14.2 Arrays操作对象数组实现排序
- Day14: 算法和数据结构
- 14.1 Lambda表达式
- 14.2 JDK8新特性(方法引用)
- 14.3 常见算法
- 14.3.1 冒泡排序
- 14.3.2 选择排序
- 14.3.3 查找算法
- 14.4 正则表达式
Day01:Java入门
1.1 Java的技术体系
- Java SE(Java Standard Edition):叫做标准版,它是后面两个版本的基础,也就是学习后面两个版本必须先学习JavaSE。
- Java EE(Java Enterprise Edition): 叫做企业版,它是为企业级应用开发提供的一套解决方案。
- Java ME(Java Micro Edition):叫做小型版,它为开发移动设备的应用提供了一套解决方案。
1.2 Java快速入门
1.2.1 JDK、JRE与JVM
1. jdk包含 JRE(Java Runtime Enviroment):意思是Java的运行环境;它是由JVM和核心类库组成的;如果你不是开发人员,只需要在电脑上安装JRE就可以运行Java程序。
2. jvm(java虚拟机):JDK最核心的组成部分是JVM(Java Virtual Machine),它是Java虚拟机,真正运行Java程序的地方。
3.JDK、JRE的关系用一句话总结就是:用JDK开发程序,交给JRE运行
4. java既是编译型(C、C++)也是解释型(javascript)语言
1.2.2 JDK环境变量配置
1.2.2.1 首先找到此电脑,右键点击属性,可以按照下面的界面;点击【高级系统设置】,再点击【环境变量】
1.2.2.2 找到JDK的bin目录,复制一下
1.2.2.3 将JDK的bin目录粘贴在Path环境变量后面
1.2.2.4.在CMD输入javac -version 看提示信息是否显示你安装JDK的版本号
1.3 Java基础语法
1.3.1 注释
1.单行注释://后面根解释文字
2.多行注释/*这里写注释文字可以写多行*/
3.文档注释/**这里写文档注释也可以写多行,文档注释可以利用JDK的工具生成帮助文档*/
1.3.2 字面量
字面量数据在程序中的书写格式
1.3.3 JAVA关键字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
1.3.4 标志符
1.3.5 变量
变量是用来记录程序中的数据的。其本质上是内存中的一块区域,你可以把这块区域理解成一个小盒子。
注意:
变量的类型只有引用数据类(数组、类接口、枚举、注解)型和基本数据类型(byte,short,int,long,float,double,char,boolean)两种。
Day02: 数据类型、运算符
2.1 数据的表示详解
2.1.1二进制
数据在计算机中都是以二进制表示的
2.2 数据的表示
数据的表示形式除了二进制(逢2进1),八进制(逢8进1)、还有十进制(逢10进1)、十六进制(逢10进1)等
2.2.1 进制转换
2.2.2.1.1 普通方法
a.二进制是如何表示十进制的2呢?
1+ 1--------------------------------10
这里两个1相加,结果为2,由于二进制满2进1,所以最终结果10
b.那么二进制是如何表示十进制的3呢?
我们已经知道二进制10表示十进制的2,那么二进制10+1就表示十进制的3啊!
10+ 1-------11十进制的3对应的二进制是11
2.2.2.1.2除2取余法
6/2 | 商 | 余数 |
---|---|---|
6/2 | 3 | 0 |
3/2 | 1 | 1 |
1/2 | 0 | 1 |
然后把余数反转:6对应的二进制是110
2.2.3 字符在计算机中的存储原理
ASCII编码表中字符编码的规律:
1.字符0对应48,后面的1,2,3,4…9 对应的十进制整数依次往后顺延
2.字符a对应97,后面的b,c,d,e…z 对应的十进制整数依次往后顺延
3.字符A对应65,后面的B,C,D,E…Z 对应的十进制整数依次往后顺延
2.2 数据类型
2.3 类型转换
2.3.1 自动类型转换
```public class Demo03 {public static void main(String[] args) {int i = 128;//byte b = (byte) i; //内存溢出double b = i;//强制转换 (类型)变量名 高到低//自动转换 低到高System.out.println(i);System.out.println(b);/*注意点1.不能对布尔值转换2.不能把对象类型转换为不相干的类型3.在把高容量转换到低容量时强制转换4.转换的时候可能存在内存溢出,或者精度问题*/System.out.println("=====================");System.out.println((int)23.7); //23System.out.println((int)-45.89f); //-45System.out.println("=====================");char c = 'a';int d = c+1;System.out.println(d);System.out.println((char)d);}
}
输出
128
128.0
=====================
23
-45
=====================
98
b
2.3.2 强制类型转换
package com.sesameseed.type;public class TypeConversionDemo3 {public static void main(String[] args) {//目标:强制类型转换int a =20;byte b = (byte)a;System.out.println(b);int i = 1500;byte j = (byte)i;System.out.println(j); //数据溢出float f1 = 12.5656F;int i1 = (int)f1;System.out.println(i1);}
}print:
20
-36
12
2.4 运算符
- 基本算术运算符
- 自增自减运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 三元运算符
2.4.1 算术运算符
2.4.2 自增自减运算符
++i:先做加法运算,再做自加
i++:先做自加,再做加法运算
package operator;public class Demo04 {public static void main(String[] args) {//++ -- 自增,自减 一元运算符int a= 3;int b = a++; //执行完这行代码后,先给b赋值,再自增// a = a+1System.out.println(a);// a = a+1;int c = ++a; //执行完这行代码前,先自增,再给b赋值System.out.println(a);System.out.println(b);System.out.println(c);//幂运算 2*3 2*2*2 = 8 很多运算用工具类来操作!double pow = Math.pow(2,3);System.out.println(pow);}
}
输出
4
5
3
5
8.0
2.4.3 赋值运算符
2.4.4 关系运算符
2.4.5 逻辑运算符
2.4.6 三元运算符
```java
package operator;//三元运算符
public class Demo08 {public static void main(String[] args) {// x ? y : z//如果x == true,则结果为y,否则为zint score = 80;String type = score < 60 ?"不及格":"及格";// ifSystem.out.println(type);}
}
输出
及格
2.4.7 运算优先级
&&运算比||运算的优先级高,所以&&和||同时存在时,是先算&&再算||;
2.5 案例技术:获取用户键盘输入的数据
package com.sesameseed.scanner;import java.util.Scanner;public class ScannerDemo1 {public static void main(String[] args) {//TODO:Scanner是键盘扫描器对象(你就把它理解成一个东西),这个东西有录入的功能//sc是给这个东西取的自定义名字Scanner sc = new Scanner(System.in);System.out.println("请输入您的年龄:");//sc这个东西有键盘录入整数的功能,这个功能的名字叫nextInt()//.表示表示调用的意思int age = sc.nextInt();System.out.println("您的年龄是:"+ age);System.out.println("请输入您的名字");//sc这个东西还有键盘录入字符串的功能,这个功能的名字叫nextString name = sc.next();System.out.println(name + "欢迎进入系统");}
}
Day03: 程序流程控制
3.1 选择结构
3.1.1 if单选择结构
package com.jiao.struct;import java.util.Scanner;public class IfDemo01 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入一个内容:");String s = scanner.nextLine();//equals:判断字符串是否相等if (s.equals("Hello")){System.out.println(s);}System.out.println("End");scanner.close();}
}输出
请输入一个内容:
Hello
Hello
End
3.1.2 if双选择结构
package com.jiao.struct;import java.util.Scanner;public class IfDemo02 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入成绩:");int score = scanner.nextInt();if (score > 60){System.out.println("及格");}else{System.out.println("不及格");}scanner.close();}
}
输出
请输入成绩:
50
不及格
3.1.3 多单选择结构
package com.jiao.struct;import java.util.Scanner;public class IfDemo03 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入成绩:");int score = scanner.nextInt();if (score == 100){System.out.println("满分");}else if(score < 100 && score >= 90){System.out.println("A");}else if(score < 90 && score >= 80){System.out.println("B");}else if(score < 80 && score >= 60){System.out.println("C");}else if(score < 60 && score >= 0){System.out.println("不及格");}else{System.out.println("输入成绩不合法");}scanner.close();}
}
输出
请输入成绩:
80
B
3.1.4 嵌套if结构
3.1.5 switch多选择结构
package com.jiao.struct;//case穿透//switch 匹配一个具体的值
public class SwitchDemo01 {public static void main(String[] args) {char grade = 'B';switch (grade){case'A':System.out.println("优秀");break; //可选,如果没有则会发生case穿透现象,即会输出下边的语句结果case'B':System.out.println("良好");break; //可选,如果没有则会发生case穿透现象,即会输出下边的语句结果case'C':System.out.println("及格");break; //可选,如果没有则会发生case穿透现象,即会输出下边的语句结果case'D':System.out.println("再接再厉");break; //可选,如果没有则会发生case穿透现象,即会输出下边的语句结果default:System.out.println("未知等级");}}
}
输出
良好
3.1.6 jdk7新特性
package com.jiao.struct;public class SwitchDemo02 {public static void main(String[] args) {String name = "李明";switch (name){case "张三":System.out.println("张三");break;case "李明":System.out.println("李明");break;default:System.out.println("输入不合法");}}
}
输出
李明
3.2 循环结构
3.2.1 while循环
package com.jiao.struct;public class WhileDemo01 {public static void main(String[] args) {//输出1~100int i = 0;while (i < 100){i++;System.out.println(i);}}
}
输出
1
2
、、、
100
package com.jiao.struct;public class WhileDemo02 {public static void main(String[] args) {//死循环while (true){//等待客户连接//定时检查}}
}
计算1+2+3+…+100 = ?
package com.jiao.struct;public class WhileDemo03 {public static void main(String[] args) {//计算1+2+3+...+100 = ?int i = 0;int sum = 0;while (i <= 100){sum = sum + i;i++;}System.out.println(sum);}
}
输出
5050
3.2.2 do…while循环
package com.jiao.struct;public class DoWhileDemo01 {public static void main(String[] args) {int i = 0;int sum = 0;do{sum = sum + i;i++;}while (i <= 100);System.out.println(sum);}}
输出
5050
package com.jiao.struct;public class DoWhileDemo02 {public static void main(String[] args) {int a = 0;while (a < 0){System.out.println(a);a++;}System.out.println("================");do {System.out.println(a);a++;}while (a < 0);}
}
输出
0
3.2.3 For循环
package com.jiao.struct;public class ForDemo01 {public static void main(String[] args) {int a = 1; //初始化条件while (a <= 100) { //条件判断System.out.println(a); //循环体a += 2; //迭代}System.out.println("while循环结束");//初始化值、条件判断、迭代for (int i = 1;i <= 100;i++){System.out.println(i);}//100.for 快捷生成 for (int i = 0; i < 100; i++)System.out.println("for循环结束");}
}
3.2.4 增强for循环
package com.jiao.struct;public class ForDemo05 {public static void main(String[] args) {int[] numbers = {10,20,30,40,50}; //定义了一个数组for (int i = 0;i < 5;i++) {System.out.println(numbers[i]);}System.out.println("=============");//遍历数组元素for (int x:numbers){ //把number赋值给intSystem.out.println(x);}}
}
输出
10
20
30
40
50
=============
10
20
30
40
50
3.3 练习
3.3.1 练习1:计算0到100间的奇数和偶数的和
package com.jiao.struct;public class ForDemo02 {public static void main(String[] args) {//练习1:计算0到100间的奇数和偶数的和int oddSum = 0;int evenSum = 0;for (int i = 0; i <= 100; i++) {if (i % 2 != 0){oddSum += i;}else {evenSum += i;}}System.out.println("奇数的和"+oddSum);System.out.println("偶数的和"+evenSum);}
}
输出
奇数的和2500
偶数的和2550
3.3.2 练习2:用while或for循环输出1~1000间能被5整除的数,并且每行输出3个
package com.jiao.struct;public class ForDemo03 {public static void main(String[] args) {//练习2:用while或for循环输出1~1000间能被5整除的数,并且每行输出3个for (int i = 0; i <= 1000; i++) {if(i % 5 == 0){System.out.print(i+"\t");}if(i % (5*3) == 0){//System.out.println(); 也可以实现System.out.println("\n");}}//println 输出完会换行//print 输出完不会换行}
}输出
0 5 10 15 20 25 30 35 40 45 50 55 60 、、、
3.3.3 练习3:输出9X9乘法表
package com.jiao.struct;public class ForDemo04 {//练习3:输出9X9乘法表public static void main(String[] args) {//1.首先打印第一列//2.把固定的1再用一个人循环包起来//3.去掉重复项 i <= j//4.调整样式for (int j = 1; j <= 9; j++) {for (int i = 1; i <= j; i++) {System.out.print(j + "*" + i + "=" + (j * i) + "\t");}System.out.println();}}
}
3.4 break和continue关键字
break作用:跳出并结束当前所在循环的执行
continue作用:结束本次循环,进入下一次循环
package com.jiao.struct;public class BreakDemo01 {public static void main(String[] args) {int i = 0;while (i < 100){i++;System.out.println(i);if(i == 30){break;}}System.out.println("123");}
}
输出
1
2
3
...
30
123
package com.jiao.struct;public class ContinueDemo01 {public static void main(String[] args) {int i = 0;while (i < 100){i++;if (i % 10 == 0){System.out.println();continue;}System.out.print(i);}}
}
输出
123456789
111213141516171819
212223242526272829
313233343536373839
414243444546474849
515253545556575859
616263646566676869
717273747576777879
818283848586878889
919293949596979899
package com.jiao.struct;public class Labe1Demo {public static void main(String[] args) {//打印101~150之间的所有质数//质数是指在大于1的自然数中,除了1和它本身以外不再有其他因素的自然数int count = 0;//不建议使用outer:for (int i = 101; i < 150; i++) {for (int j = 2; j < i/2; j++) {if (i % j == 0){continue outer;}}System.out.println(i+"");}}
}
输出
101 103 107 109 113 127 131 137 139 149
package com.jiao.struct;import javax.xml.transform.Source;public class TextDemo01 {//打印5行的三角形public static void main(String[] args) {for (int i = 1; i <= 5; i++) {for (int j = 5; j >= i; j--) {System.out.print(" ");}for (int j = 1; j <= i; j++) {System.out.print("*");}for (int j = 1; j < i; j++) {System.out.print("*");}System.out.println();}}
}
输出*************************
3.5 随机数
3.5.1 产生一个随机数
package com.sesameseed.random;import java.util.Random;public class RandomDemo {public static void main(String[] args) {// 2、创建一个Random对象,用于生成随机数。Random r1 = new Random();for (int i = 1;i <= 20;i++) {int data = r1.nextInt(10);System.out.println(data);}System.out.println("=======0~10的随机数=========");for (int i = 1;i <= 20;i++) {// 3、调用Random提供的功能:nextInt得到随机数。int data2 = r1.nextInt(10) + 1;System.out.println(data2);}System.out.println("=======0~20的随机数=========");for (int i = 1;i <= 20;i++) {int data2 = r1.nextInt(10) + 11;System.out.println(data2);}}
}
3.5.2 猜数字小游戏
package com.sesameseed.random;import java.util.Random;
import java.util.Scanner;public class RandomTest {public static void main(String[] args) {// 1、随机产生一个1-100之间的数据,做为中奖号码。Random r = new Random();int lukyNum = r.nextInt(100) + 1;// 2、定义一个死循环,让用户不断的猜测数据Scanner sc = new Scanner(System.in);while (true){System.out.println("请输入您猜测的数据");int guessNum = sc.nextInt();if (guessNum > lukyNum){System.out.println("猜大了");} else if (guessNum < lukyNum){System.out.println("猜小了");} else {System.out.println("成功");break;}sc.close(); //凡是属于IO(输入、输出)流的类如果不关闭会一直占用资源}}
}
Day04: Java数组
数组就是一个容器,用来存同种类型的数据的
比如:要存储 “牛二“,“西门“,“全蛋“ 这些数据。
String[] names = {"牛二", "西门", "全蛋"};
4.1 认识数组
数组就是一个容器,用来存一批同种类型的数据的。
int[] array = {20,10,80,60,90};
//比如:想要存储 20,10,80,60,90 这些数据。 我们可以把代码写成这样
4.2 数组的定义和访问
4.2.1静态初始化
语法简化格式:数据类型[ ] 变量名 = {元素1,元素2,元素3};
//定义数组,用来存储多个年龄
int[] ages = {12, 24, 36}
4.2.2 数组的动态初始化
格式如下:
int[] arr = new int[3]; //数据类型[] 数组名 = new 数据类型[长度];
注意:
使用动态初始化定义数组时,根据元素类型不同,默认值也有所不同。
数组动态初始化案例
package com.sesameseed.array;public class ArrayDemo4 {public static void main(String[] args) {//TODO 动态初始化数组//1.数据类型[] 数组名 = new 数据类型[长度]int[] ages = new int[3];System.out.println(ages[0]);System.out.println(ages[1]);System.out.println(ages[2]);ages[0] = 11;ages[1] = 22;ages[0] = 33;System.out.println(ages[0]);System.out.println(ages[1]);System.out.println(ages[2]);System.out.println("=====其他数据类型元素默认值=====");char[] ch1 = new char[3]; //char的默认值0System.out.println((int) ch1[0]);System.out.println((int) ch1[1]);System.out.println((int) ch1[2]);double[] d1 = new double[3]; //double的默认值0System.out.println((int) d1[0]);System.out.println((int) d1[1]);System.out.println((int) d1[2]);String[] s1 = new String[3]; //String的默认值nullSystem.out.println(s1[0]);System.out.println(s1[1]);System.out.println(s1[2]);boolean[] b1 = new boolean[3]; //boolean的默认值falseSystem.out.println(b1[0]);System.out.println(b1[1]);System.out.println(b1[2]);}
}
4.3 内存分析
注意:
基本数据类型储存的是变量,引用数据(如:string)类型储存的是地址(Unicode编码表)
4.4 数组在计算机中的执行原理
注意:
- a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
- arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
4.5 多个变量指向同一个数组的问题
public class ArrayDemo2 {public static void main(String[] args) {// 目标:认识多个变量指向同一个数组对象的形式,并掌握其注意事项。int[] arr1 = {11, 22, 33};// 把int类型的数组变量arr1赋值给int类型的数组变量arr2int[] arr2 = arr1;System.out.println(arr1);System.out.println(arr2);arr2[1] = 99;System.out.println(arr1[1]);arr2 = null; // 拿到的数组变量中存储的值是nullSystem.out.println(arr2);//System.out.println(arr2[0]);//System.out.println(arr2.length);}
}
关注这一段代码
4.6 数组练习
4.6.1 数组求最值
package com.sesameseed.TestDemo;public class TestDemo1 {public static void main(String[] args) {// TODO 定义一个int类型数组,求数组中元素的最大值,并打印最大值int[] faceScores = {15, 9000, 10000, 20000, 9500, -5};// 2、定义一个变量用于最终记住最大值int max1 = faceScores[0];// 3、从数组的第二个位置开始遍历。for (int i = 1; i < faceScores.length; i++) {// i = 1 2 3 4 5// 判断一下当前遍历的这个数据,是否大于最大值变量max存储的数据,//如果大于,当前遍历的数据需要赋值给maxif (faceScores[i] >max1){max1 = faceScores[i];}}System.out.println("最大值" + max1);}
}
4.6.2 数组存取用户数据进行随机排名
package com.sesameseed.TestDemo;import java.util.Random;
import java.util.Scanner;public class TestDemo5 {public static void main(String[] args) {//TODO 随机排名// 1、定义一个动态初始化的数组用于存储5名员工的工号int[] codes = new int[5];// 2、提示用户录入5名员工的工号。Scanner sc = new Scanner(System.in);for (int i = 0; i < codes.length; i++) {System.out.println("请你输入当前第" + (i + 1) + "员工编号");int code = sc.nextInt();codes[i] = code;}// 3、打乱数组中的元素顺序。// [12, 33, 54, 26, 8]// i indexRandom r = new Random();for (int i = 0; i < codes.length; i++) {// codes[i]// 每遍历到一个数据,都随机一个数组索引范围内的值。//然后让当前遍历的数据与该索引位置处的值交换。int index = r.nextInt(codes.length);// 定义一个临时变量记住index位置处的值int temp = codes[index];// 把i位置处的值赋值给index位置处codes[index] = codes[i];// 把index位置原来的值赋值给i位置处codes[i] = temp;}// 4、遍历数组中的工号输出即可for (int i = 0; i < codes.length; i++) {System.out.print(codes[i] + " ");}}
}
4.6.3 冒泡排序
package com.sesameseed.TestDemo;import java.util.Arrays;public class TestDemo2 {public static void main(String[] args) {int[] a = {1,54,5,8,99,58};int[] sort = sort(a); //调用完我们自己写的排序方法以后,返回一个排序后的数组System.out.println(Arrays.toString(sort));}//冒泡排序//1、比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置//2、每一次比较,都会产生出一个最大,或者最小的数字//3、下一轮这可以少一排序//4、依次循环直到结束public static int[] sort(int[] array) {//临时变量int temp ;//外层循环,判断我们这个要走多少次for (int i = 0; i < array.length-1; i++) {//内层循环,比较判断两个数,如果第一个数比第二个数大,则交换位置for (int j = 0; j < array.length-1-i; j++) {if (array[j+1] > array[j]){temp = array[j];array[j] = array[j+1];array[j+1] = temp;}}}return array;}
}
4.6.4 数组元素反转
package com.sesameseed.TestDemo;public class TestDemo3 {public static void main(String[] args) {//TODO 数组元素反转int[] arr1 = {10, 20, 30, 5, 3};for (int i = 0, j = arr1.length - 1; i < j; i++, j--) {// 1、定义一个临时变量记住后一个位置处的值int temp = arr1[j];// 2、把前一个位置处的值赋值给后一个位置了arr1[j] = arr1[i];// 3、把临时变量中记住的后一个位置处的值赋值给前一个位置处arr1[i] = temp;}// 3、遍历数组中的每个数据,看是否反转成功了for (int i = 0; i < arr1.length; i++) {System.out.print(arr1[i] + " ");}}
}
4.7 Debug调试
第一步:打断点,如下图的红色小圆点
第二步:右键Debug方式启动程序
启动后,代码会停留在打断点的这一行
第三步:点击箭头按钮,一行一行往下执行
Day05: 方法
方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用。
5.1 方法概述
package com.sesameseed.method;public class MethonDemo1 {public static void main(String[] args) {//TODO 掌握定义方法的完整格式//调用方法int rs = sum(10,20);System.out.println("和是:" + rs);}//定义方法public static int sum(int a ,int b){int c = a + b;return c;}
}
5.2 方法的定义
5.3 方法在计算机中的执行原理
5.3.1 有返回值的方法,内存分析
package com.sesameseed.method;public class TestDemo1 {//TODO 有返回值,可以直接调用public static void main(String[] args) {int count1 = paperCount(0.1,8848000);System.out.println(count1);}public static int paperCount(double paperWidth,double mountainHeig){int count = 0;while (paperWidth < mountainHeig){paperWidth *= 2;count++;}return count;}
}
5.3.2 无返回值的方法,内存分析
package com.sesameseed.method;public class TestDemo2 {//TODO 无返回值语法格式,不能调用,在方法中要打印输出public static void main(String[] args) {paperCount(0.1,8848000);}public static void paperCount(double paperWidth,double mountainHeig){int count = 0;while (paperWidth < mountainHeig){paperWidth *= 2;count++;}System.out.println(count);}
}
5.4 方法参数的传递机制
5.4.1 方法参数传递是基本类型数据,内存执行原理
Java的参数传递机制都是:值传递,传递的是实参存储的值的副本。
5.4.2 参数是引用类型,实际上也是值传递,只不过参数传递存储的地址值
总结一下:
基本类型和引用类型的参数在传递的时候有什么不同?
都是值传递
- 基本类型的参数传递存储的数据值。
- 引用类型的参数传递存储的地址值。
5.4.3 方法参数传递案例1
public class MethodTest3 {public static void main(String[] args) {// 目标:完成打印int类型的数组内容。int[] arr = {10, 30, 50, 70};printArray(arr);int[] arr2 = null;printArray(arr2);int[] arr3 = {};printArray(arr3);}/*参数:int[] arr表示要被打印元素的数组,需要调用者传递*/public static void printArray(int[] arr){if(arr == null){System.out.println(arr); // nullreturn; // 跳出当前方法}System.out.print("[");// 直接遍历接到的数组元素for (int i = 0; i < arr.length; i++) {if(i == arr.length - 1){System.out.print(arr[i]);}else {System.out.print(arr[i] + ", ");}}System.out.println("]");}
}
5.5 方法重载
重载指:一个类中,出现多个相同方法名,但它们的形参列表不同,叫方法重载。
5.5.1 方法重载案例一
package com.jiao.method;public class Demo02 {public static void main(String[] args) {int max = max(10, 20);System.out.println(max);}//比大小public static int max(int num1,int num2){int result = -1;if (num1 == num2){System.out.println("num1 == num2");return 0; //终止方法}if (num1 > num2){result = num1;}else {result = num2;}return result;}public static double max(double num1,double num2){double result = -1;if (num1 == num2){System.out.println("num1 == num2");return 0; //终止方法}if (num1 > num2){result = num1;}else {result = num2;}return result;}
}
5.5.2 方法重载案例二
package com.sesameseed.parameter;public class MethodOverDemo1 {public static void main(String[] args) {//方法重载fire();fire("岛国2");fire("米国",999);}public static void fire(){fire("岛国");}public static void fire(String country){fire(country,1);}public static void fire(String country,int number){System.out.println("发射了" + number + "枚武器给" + country);//发射了1枚武器给岛国//发射了1枚武器给岛国2//发射了999枚武器给米国}
}
5.6 return单独使用
return跳出当前方法
package com.sesameseed.returndemo;public class ReturnDemo1 {public static void main(String[] args) {//TODO return跳出当前方法System.out.println("开始");chu(10,0);System.out.println("结束");}public static void chu(int a, int b){if (b == 0){System.out.println("您的数据有误,不执行");return; // 直接跳出并结束当前chu方法的执行}int c = a / b;System.out.println("除法结果是:" + c);}
}
//开始
//您的数据有误,不执行
//结束
Day06: Java编程案例思维训练
6.1 完成买飞机票的案例
package com.sesameseed.testdemo;import java.util.Scanner;public class Test1 {public static void main(String[] args) {// TODO:完成买飞机票的案例。System.out.println("获取实付价:");Scanner sc = new Scanner(System.in);int price = sc.nextInt();System.out.println("获取月份:");Scanner sc2 = new Scanner(System.in);int month = sc2.nextInt();System.out.println("获取舱机类型:");Scanner sc3 = new Scanner(System.in);String type = sc3.nextLine();
// switch (type){// case "1":
// System.out.println("经济舱");
// } 通过switch对应数字实现对经济头等舱的选择double fanalP = calculate(price,month,type);//double fanalP= calculate(1000,12,"头等舱");System.out.println("最终优惠价:" + fanalP);}public static double calculate(double price,int month,String type){if (month >= 5 && month <= 10){switch (type){case "头等舱":price *= 0.9;break;case "经济舱":price *= 0.85;break;}}else {switch (type){case "头等舱":price *= 0.7;break;case "经济舱":price *= 0.65;break;}}return price;}
}
6.2 完成生成随机验证码
package com.sesameseed.testdemo;import java.util.Random;public class Test2 {public static void main(String[] args) {//TODO 目标:完成生成随机验证码。System.out.println(getCode(3));}public static String getCode(int n){String getcode = "";Random r = new Random();for (int i = 0; i <= n; i++) {int num = r.nextInt(3);switch (num){case 0:getcode += r.nextInt(10);break;case 1:char ch1 = (char)(r.nextInt(26) + 65);getcode += ch1;break;case 2:char ch2 = (char) (r.nextInt(26)+97);getcode += ch2;break;}}return getcode;}
}
Day07:Java面向对象基础
对象实质上是一种特殊的数据结构,一句话总结,对象其实就是一张数据表,表当中记录什么数据,对象就处理什么数据。
7.1 对象在计算机中的执行原理
说明:
Student s1
表示的是在栈内存中,创建了一个Student类型的变量,变量名为s1- 而
new Student()
会在堆内存中创建一个对象,而对象中包含学生的属性名和属性值- 同时系统会为这个Student对象分配一个地址值0x4f3f5b24
- 接着把对象的地址赋值给栈内存中的变量s1,通过s1记录的地址就可以找到这个对象
- 当执行
s1.name=“播妞”
时,其实就是通过s1找到对象的地址,再通过对象找到对象的name属性,再给对象的name属性赋值为播妞
;
7.2 类和对象的一些注意事项
7.3 this关键字
哪一个对象调用方法方法中的this就是哪一个对象
7.4 构造器
什么是构造器?
构造器其实是一种特殊的方法,但是这个方法没有返回值类型,方法名必须和类名相同**。
构造器的特点?
new 对象就是在执行构造方法 !!!在创建对象时,会调用构造器。也就是说
new Student()
就是在执行构造器,当构造器执行完了,也就意味着对象创建成功。
当执行new Student("播仔",99)
创建对象时,就是在执行有参数构造器,当有参数构造器执行完,就意味着对象创建完毕了。
7.5 封装性
封装,就是用类设计对象处理某一个事物的数据时,把要处理的数据,处理数据的方法,设计到一个对象中。
合理隐藏、合理暴露
7.6 实体JavaBean
需要满足下面的要求
实体(JavaBean)类特点:
1、实体(JavaBean)类用来封装数据,只提供对数据进行存和取的方法
2、必须私有成员变量,并为每个变量通提供get、 set方法
案例一:
package com.sesameseed.javabean;public class Student {//实体类(JavaBean)特点:用来封装数据,只提供对数据进行存和取的方法//1.必须私有成员变量,并为每个变量通提供get set方法private String name;private double score;// 3.建议为类提供一个公开的有参数构造器给别人调用,公共的无参构造器,设计示例要求public Student(String name, double score) {this.name = name;this.score = score;}//2.必须为类提供一个公开的无参数构造器public Student() {}public String getName() { //调用get方法,需要次方法传输数据return name;}public void setName(String name) { //调用set方法,需要次方法接受数据this.name = name;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}
}
7.6.1 实体类案例一
7.6.2 面向对象综合案例
Movie对象封装类
package com.sesameseed.oop.oopdemo2;public class Movie {//set赋值//get取值private int id;private String name;private double price;private double score;private String director;private String actor;private String info;//公共的无参构造器,设计示例要求public Movie() {}//公共的有参构造器,方便创建对象赋值public Movie(int id, String name, double price, double score, String director, String actor, String info) {this.id = id;this.name = name;this.price = price;this.score = score;this.director = director;this.actor = actor;this.info = info;}public int getId() { //get取值return id;}public void setId(int id) { //set赋值this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}public String getDirector() {return director;}public void setDirector(String director) {this.director = director;}public String getActor() {return actor;}public void setActor(String actor) {this.actor = actor;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}
}
MovieOperator 操作类
package com.sesameseed.oop.oopdemo2;public class MovieOperator {private Movie[] movies; //定义一个电影类型的数组public MovieOperator(Movie[] movies){//因为系统中有多部电影,所以电影操作类中,需要有一个Movie的数组this.movies = movies;}// 1、展示系统全部电影信息 movies = [m1, m2, m3, ...]public void printAllMovies(){System.out.println("==系统全部信息如下==");for (int i = 0; i < movies.length; i++) {Movie m = movies[i];System.out.println("编号" + m.getId());System.out.println("名称" + m.getName());System.out.println("价格" + m.getPrice());System.out.println("==========");}}// 2、根据电影的编号查询出该电影的详细信息并展示public void searchMovieById(int id){ //展示信息,不用返回for (int i = 0; i < movies.length; i++) {Movie m = movies[i]; //遍历电影中每个对象,用变量m记住if (m.getId() == id){System.out.println("已查询到该电影,该电影的信息如下");System.out.println(m.getId());System.out.println(m.getName());System.out.println(m.getScore());System.out.println(m.getDirector());System.out.println(m.getActor());System.out.println(m.getInfo());return;}}System.out.println("无此电影");}// 2、根据电影的名称查询出该电影的详细信息并展示public void searchMovieByName(String name){for (int i = 0; i < movies.length; i++) {Movie m = movies[i]; //遍历电影中每个对象,用变量m记住
// if (m.getName() == name){if (m.getName().equals(name)){System.out.println("已查询到该电影,该电影的信息如下");System.out.println(m.getId());System.out.println(m.getName());System.out.println(m.getScore());System.out.println(m.getDirector());System.out.println(m.getActor());System.out.println(m.getInfo());return;}}System.out.println("无此电影");}
}
Test测试类
package com.sesameseed.oop.oopdemo2;import java.util.Scanner;public class Test {public static void main(String[] args) {Movie[] m = new Movie[4];//调用公共的有参构造器Movie m1 = new Movie(1,"水门桥", 38.9, 9.8, "徐克", "吴京","12万人想看");Movie m2 = new Movie(2, "出拳吧", 39, 7.8, "唐晓白", "田雨","3.5万人想看");Movie m3 = new Movie(3,"月球陨落", 42, 7.9, "罗兰", "贝瑞","17.9万人想看");Movie m4 = new Movie(4,"一点就到家", 35, 8.7, "许宏宇", "刘昊然","10.8万人想看");m[0] = m1;m[1] = m2;m[2] = m3;m[3] = m4;MovieOperator movieOperator = new MovieOperator(m);
// movieOperator.printAllMovies();
// movieOperator.searchMovieById(5);Scanner scanner = new Scanner(System.in);while (true) {System.out.println("请输入命令1.展示全部 2.id查询 3.名称查询");
// Scanner scanner = new Scanner(System.in); //放置循环外,减少内存占用int command = scanner.nextInt();switch (command){case 1:System.out.println("全部信息如下");movieOperator.printAllMovies();break;case 2:System.out.println("输入影片id信息");int i = scanner.nextInt();movieOperator.searchMovieById(i);break;case 3:System.out.println("输入影片名称信息");String s = scanner.next();movieOperator.searchMovieByName(s);break;default:System.out.println("无此操作");}}}
}
7.7 成员变量和局部变量的区别
Day08: Java常用API
8.1 String类
string 的指针从0开始,它是有下标的!
package com.sesameseed.string;public class Demo2 {public static void main(String[] args) {//TODO 快速熟悉String提供的处理字符串的常用方法。String s1 = "sdas小明";// 1、获取字符串的长度System.out.println(s1.length());// 2、提取字符串中某个索引位置处的字符System.out.println(s1.charAt(2));// 字符串的遍历for (int i = 0; i < s1.length(); i++) {char c1 = s1.charAt(2);System.out.println(c1);}// 3、把字符串转换成字符数组,再进行遍历char[] c2 = s1.toCharArray();for (int i = 0; i < c2.length; i++) {System.out.println(c2[i]);}//4、判断字符串内容,内容一样就返回true
// String s2 = new String("54sdaA");
// String s3 = new String("54sdaA");String s2 ="54sdaA";String s3 = "54sdaA";//true 解释:都是在一个容器内创建,此种方式在字符串常量池中进行创建,第二次创建,跟字符串常量池进行比较,如果有直接饮用System.out.println(s2 == s3);//false 解释:System.out.println(s2.equals(s3)); //true// 5、忽略大小写比较字符串内容String s4 ="54sdaa";String s5 = "54sdaA";System.out.println(s4.equals(s5)); //falseSystem.out.println(s4.equalsIgnoreCase(s5)); //true// 6、截取字符串内容 (包前不包后的)String s7 = s1.substring(0,2);System.out.println(s7);// 7、从当前索引位置一直截取到字符串的末尾String s6 = s1.substring(2);System.out.println(s6);// 8、把字符串中的某个内容替换成新内容,并返回新的字符串对象给我们String trans = "好垃圾";String s8 = trans.replace("垃圾","**");System.out.println(s8);}
}
package com.sesameseed.string;import java.util.Random;public class StringTest2 {public static void main(String[] args) {//TODO 随机生成验证码System.out.println(createCode(4));}public static String createCode(int n){// 2、定义2个变量//一个是记住最终产生的随机验证码//一个是记住可能用到的全部字符String ranCode = "";String data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";Random r1 = new Random(); // 3、开始定义一个循环产生每位随机字符for (int i = 0; i < n; i++) { //循环n次产生n个随机数int index = r1.nextInt(data.length()); // 4、随机一个字符范围内的索引。ranCode += data.charAt(index); // 2、提取字符串中某个索引位置处的字符}return ranCode;}
}
8.2 ArrayList类
package com.sesameseed.arraylist;import java.util.ArrayList;public class Demo2 {public static void main(String[] args) {//1.创建一个ArrayList的集合对象ArrayList<String> list = new ArrayList<>();list.add("第一个");list.add("第二个");list.add("第三个");System.out.println(list); //[第一个, 第二个, 第三个]// 2、往集合中的某个索引位置处添加一个数据list.add(1,"mysql");System.out.println(list); //[第一个, mysql, 第二个, 第三个]// 3、根据索引获取集合中某个索引位置处的值String st1 = list.get(1);System.out.println(st1); //mysql// 4、获取集合的大小(返回集合中存储的元素个数)System.out.println(list.size()); //4// 5、根据索引删除集合中的某个元素值,会返回被删除的元素值给我们System.out.println(list.remove(1));System.out.println(list); //[第一个, 第二个, 第三个]// 6、直接删除某个元素值,删除成功会返回true,反之System.out.println(list.remove("java")); //falseSystem.out.println(list); //[第一个, 第二个, 第三个]// 默认删除的是第一次出现的数据的list.add("第一个");System.out.println(list); //[第一个, 第二个, 第三个, 第一个]System.out.println(list.remove("第一个")); //true 删除成功System.out.println(list); //[第二个, 第三个, 第一个]// 7、修改某个索引位置处的数据,修改后会返回原来的值给我们System.out.println(list.set(1,"修改后的第三个")); //第三个System.out.println(list); //[第二个, 修改后的第一次, 第一个]}
}
package com.sesameseed.arraylist;import java.util.ArrayList;public class Demo1 {public static void main(String[] args) {//TODO 删除指定元素ArrayList<String> l1 = new ArrayList<>();// 1、创建一个ArrayList的集合对象l1.add("枸杞");l1.add("Java入门");l1.add("宁夏枸杞");l1.add("黑枸杞");l1.add("人字拖");l1.add("枸杞子");System.out.println(l1);// 2、开始完成需求:从集合中找出包含枸杞的数据并删除它
// for (int i = 0; i < l1.size(); i++) {// String del = l1.get(i);
// if (del.contains("枸杞")){// l1.remove(i);
// i--; //处理每次元素删除,元素重新前移,不能删除成功 bug
// }
// }for (int i = l1.size() - 1; i >= 0; i--) {String del = l1.get(i);if (del.contains("枸杞")){ // 9、contains关键字判断字符串中是否包含某个关键字
// l1.remove(i);//使用索引删除
// l1.remove(i);//使用指定元素删除??????}}System.out.println(l1);}
}
Day09: Java基础项目(ATM系统)
package com.sesameseed.atm;public class Account {/** 有无参构造:* 为外部类调用方法提供接口* construction构造器:同理* *///封装相关对象private String carID;private String userName;private char sex;private String pwd;private double money;private double limit; //限制public String getCarID() {return carID;}public void setCarID(String carID) {this.carID = carID;}public String getUserName() {// return userName;return userName + (sex == '男' ? "先生" : "女士");}public void setUserName(String userName) {this.userName = userName;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}public double getLimit() {return limit;}public void setLimit(double limit) {this.limit = limit;}public Account() {}public Account(String carID, String userName, char sex, String pwd, double money, double limit) {this.carID = carID;this.userName = userName;this.sex = sex;this.pwd = pwd;this.money = money;this.limit = limit;}
}
package com.sesameseed.atm;import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;public class ATM {//优化代码//定义在全局变量方便所有方法调用//scanner定义在全局变量,这样就不用每次都创建一个扫描器private ArrayList<Account> accounts = new ArrayList<>();Scanner sc1 = new Scanner(System.in);private Account loginAcc; //记住登录后的用户账户//开始界面方法public void start() {while (true) {System.out.println("==欢迎登录ATM系统==");System.out.println("1.用户登录");System.out.println("2.用户开户");System.out.println("3.退出系统");System.out.println("请选择:");
// Scanner sc1 = new Scanner(System.in);//放置全局变量处,方便全部方法调用int command = sc1.nextInt();switch (command) {case 1://1.调用用户登录方法login();break;case 2://2.用户开户createAccount();break;case 3://3.退出系统return;default:System.out.println("没有此操作");break;}}}//账户开户方法public void createAccount() {System.out.println("==账户开户操作==");Account acc = new Account();System.out.println("请输入你的账户名:");String name = sc1.next();acc.setUserName(name);while (true) {System.out.println("==请输入您的性别==");String st1 = sc1.next();char sex = st1.charAt(0);
// char sex = sc1.next().charAt(0);if (st1.length() == 1 && (sex == '男' || sex == '女')) {acc.setSex(sex);break;} else {System.out.println("输入只能是男、女,请重新输入");}}while (true) {System.out.println("请输入账户密码");String pwd = sc1.next();System.out.println("请再次输入密码");String retpwd = sc1.next();//密码校验if (pwd.equals(retpwd)) {acc.setPwd(retpwd);break;} else {System.out.println("输入不一致,请重新输入");}}System.out.println("请输入您的取现额度");double limit = sc1.nextDouble();acc.setLimit(limit);String newCarId = createCarId();acc.setCarID(newCarId);accounts.add(acc);System.out.println("恭喜您" + acc.getUserName() + "开户成功,你的卡号是:" + acc.getCarID());}//生成卡号方法private String createCarId() {while (true) {// 1、使用循环,循环8次,每次产生一个随机数给cardId连接起来Random r = new Random();// 2、定义一个String类型的变量记住8位数字作为一个卡号String cardId = "";for (int i = 0; i < 8; i++) {int data = r.nextInt(10);cardId += data;}// 3、判断cardId中记住的卡号,是否与其他账户的卡号重复了,没有重复,才可以做为一个新卡号返回。Account acc = getAccountByCardId(cardId);if (acc == null) {// 说明cardId没有找到账户对象,因此cardId没有与其他账户的卡号重复,可以返回它做为一个新卡号return cardId;}}}//判断卡号是否存在的方法private Account getAccountByCardId(String cardId) {for (int i = 0; i < accounts.size(); i++) {Account acc = accounts.get(i);if (acc.getCarID().equals(cardId)) {return acc;}}return null;}//登录方法private void login() {System.out.println("系统登录");//1.判断系统中是否有账户对象,存在才能登录,不存在,结束登录if (accounts.size() == 0) {System.out.println("当前无账户,请开户");return;}//2.系统中存在账户,可以登陆while (true) {System.out.println("请输入您的卡号");String carId = sc1.next();//调用getAccountByCardId 通过地址值,判断账户对象中是否有此账户Account acc = getAccountByCardId(carId);if (acc == null) {System.out.println("无此卡号,请确认");} else {while (true) {System.out.println("请您输入密码");String pwd = sc1.next();if (acc.getPwd().equals(pwd)) {System.out.println("恭喜您," + acc.getUserName() + "成功登录系统,您的卡号是:" + acc.getCarID());
// System.out.println("i am here");loginAcc = acc;//为了在其他任何地方调用,使用acc变量,将acc变量变为成员变量loginAcc//调用展示用户登录页面方法showUserCommand();return;//调用并结束当前登录方法} else {System.out.println("您输入的密码不正确,请确认");}}}}}//展示用户登录页面private void showUserCommand() {while (true) {// System.out.println("i am here");System.out.println(loginAcc.getUserName() + "您可以选择如下功能进行账户的处理");System.out.println("1.查询账户");System.out.println("2.存款");System.out.println("3.取款");System.out.println("4.转账");System.out.println("5.密码修改");System.out.println("6.退出");System.out.println("7.注销当前账户");System.out.println("请选择");int command = sc1.nextInt();switch (command) {case 1:// 1.查询账户showLoginAccount();break;case 2:// 2.存款saveMoney();break;case 3:// 3.取款drawMoney();break;case 4:// 4.转账transmoney();break;case 5:// 5.密码修改updatePwd();return;case 6:System.out.println(loginAcc.getUserName() + "您退出成功!");// 6.退出return;case 7:// 7.注销当前账户if (delectAccount()){return;}break;default:System.out.println("不存在次操作请重新输入");}}}//密码修改private void updatePwd() {System.out.println("账户密码修改操作");while (true) {//1.提醒用户认证当前密码System.out.println("请输入当前账户密码");String pwd = sc1.next();//验证当前密码是否正确if (loginAcc.getPwd().equals(pwd)){while (true){//当前密码正确System.out.println("请输入新密码");String newPwd = sc1.next();System.out.println("请再次输入新密码");String okPwd = sc1.next();//判断两次输入的密码是否一致if (okPwd.equals(newPwd)){loginAcc.setPwd(okPwd);System.out.println("密码修改成功");return;}else {System.out.println("您输入的两次密码不一致");}}}else {//当前密码不正确System.out.println("您当前输入密码不正确");}}}//销户private boolean delectAccount() {System.out.println("进行销户操作");//1.询问用户是否确定销户System.out.println("请问确认销户吗?y/n");String command = sc1.next();switch (command){case "y"://2.确实要销户//判断用户账户是否有钱if (loginAcc.getMoney() == 0){accounts.remove(loginAcc);System.out.println("销户成功");return true;}else {System.out.println("您的账户存在余额,不能销户");return false;}default:System.out.println("好的,账户保留");return false;}}//转账private void transmoney() {System.out.println("用户转账");//判断系统中是否存在其他账户if (accounts.size() < 2){System.out.println("一个账户,不能转账");return;//判断自己账户是否有钱}else if (loginAcc.getMoney() == 0){System.out.println("金额不足");return;}//判断自己是否有钱if (loginAcc.getMoney() == 0){System.out.println("你没钱了");return;}//开始转账while (true) {System.out.println("请输入对方的卡号");//扫描器,得到对方卡号String cardId = sc1.next();Account acc = getAccountByCardId(cardId); //把getAccountByCardId相关对象的信息赋值给Account这个变量类型if (acc == null){System.out.println("对方的卡号不存在");}else {//对方卡号存在,继续让用户认证姓氏String name = "*" + acc.getUserName().substring(1);System.out.println("请输入【" + name + "】的姓氏");String preName = sc1.next();if (acc.getUserName().startsWith(preName)){while (true){System.out.println("请输入转账金额");double money = sc1.nextDouble();//判断这个金额是否超过自己的余额if (loginAcc.getMoney() >= money){loginAcc.setMoney(loginAcc.getMoney() - money);acc.setMoney(acc.getMoney() + money); //acc为对方的相关信息,因此可以完成对方账户的转账操作System.out.println("转账成功");return;}else {System.out.println("余额不足,最多可转" + loginAcc.getMoney());}}}}}}//取钱private void drawMoney() {System.out.println("取钱操作");if (loginAcc.getMoney() < 100){System.out.println("余额不足100,禁止取钱");return;}while (true) {System.out.println("请输入取款金额");double money = sc1.nextDouble();
/*// if (loginAcc.getMoney() >= money || money > loginAcc.getLimit()){if (loginAcc.getMoney() >= money) {if (money > loginAcc.getLimit()) {System.out.println("取款超过限额,每次最多可取" + loginAcc.getMoney());} else {loginAcc.setMoney(loginAcc.getMoney() - money);System.out.println("取款" + money + "成功,余额:" + loginAcc.getMoney());return;}}else {System.out.println("余额不足,您的账户余额是" + loginAcc.getMoney());}}*/if (loginAcc.getMoney() <= money && money > loginAcc.getLimit()) {System.out.println("取款超过限额,每次最多可取" + loginAcc.getMoney());} else {loginAcc.setMoney(loginAcc.getMoney() - money);System.out.println("取款" + money + "成功,余额:" + loginAcc.getMoney());return;}if (money > loginAcc.getMoney()){System.out.println("余额不足,您的余额" + loginAcc.getMoney() );}}}//存钱private void saveMoney() {System.out.println("存钱操作");System.out.println("请输入存款金额");double money = sc1.nextDouble();loginAcc.setMoney(loginAcc.getMoney() + money);System.out.println("您存款" + money + "成功,当前余额:" + loginAcc.getMoney());}//展示当前用户所有信息private void showLoginAccount() {System.out.println("当前账户信息如下");System.out.println("卡号:" + loginAcc.getCarID());System.out.println("户主:" + loginAcc.getUserName());System.out.println("性别:" + loginAcc.getSex());System.out.println("余额:" + loginAcc.getMoney());System.out.println("每次取现额度:" + loginAcc.getLimit());}
}
package com.sesameseed.atm;public class Test {public static void main(String[] args) {// TODO ATM系统ATM atm = new ATM(); //创建一个ATM对象atm.start(); //调用ATM的start方法}
}
Day10:面向对象高级
10.1 “static” 关键字
10.1.1 static修饰成员变量
Java中的成员变量按照有无static修饰分为两种:类变量、实例变量。
注意:
由于静态变量是属于类的,只需要通过类名就可以调用:类名.静态变量.
实例变量是属于对象的,需要通过对象才能调用:对象.实例变量
10.1.1.1 static修饰成员变量 案例一
package com.sesameseed.p1_staticdemo.demo2;public class Student {// 类变量static String name;//实例变量(对象的变量)int age;
}
package com.sesameseed.p1_staticdemo.demo2;public class Test {public static void main(String[] args) {// 目标:掌握有无static修饰成员变量的用法,特点。// 1、类变量的用法。// 类名.类变量(推荐)Student.name = "李明";System.out.println(Student.name);// 对象.类变量(不推荐)Student student = new Student();student.age = 22;System.out.println(student.age);}
}
10.1.1.2 static修饰成员变量 案例二
package com.sesameseed.p1_staticdemo.demo1;public class User {//类变量:记录变量的创建次数public static int number;//构造器public User(){// 如何在自己的类中,获取类变量//方式一 :this所在的方法被哪个对象调用,this代表哪个对象
// this.number++;//方式二 类名User.number++; //推荐!!!//方式三 就近原则 先在自己所在的位置找,然后再在全局中找
// User.number++;}
}
package com.sesameseed.p1_staticdemo.demo1;public class Test {public static void main(String[] args) {//创建4个对象User u1 = new User();User u2 = new User();User u3 = new User();//查看系统创建了多少个User对象System.out.println(User.number);}
}
10.1.2 内存原理
注意:
- 1.类变量:属于类,在内存中只有一份,用类名调用
- 2.实例变量:属于对象,每一个对象都有一份,用对象调用
10.1.3 static修饰成员方法
有无static也分为两类:类方法、实例方法
有static修饰的方法,是属于类的,称为类方法;调用时直接用类名调用即可
10.1.3.1 static修饰成员方法案例一
package com.sesameseed.p1_staticdemo.demo3;public class Student {double score;//类方法:public static void printHelloWorld(){System.out.println("Hello World!");System.out.println("Hello World!");}public Student() {}public double getScore() {return score;}public void setScore(double score) {this.score = score;}public Student(double score) {this.score = score;}//实例方法(对象的方法)public void printPass(){//打印成绩是否合格System.out.println(score>=60?"成绩合格":"成绩不合格");}
}
package com.sesameseed.p1_staticdemo.demo3;public class Test {public static void main(String[] args) {//1.调用Student类中的类方法Student.printHelloWorld();//2.调用Student类中的实例方法Student student = new Student();student.setScore(99.0);student.printPass();}}
10.1.4 内存分析
- 1.类方法:static修饰的方法,可以被类名调用,是因为它是随着类的加载而加载的。
- 2.实例方法:非static修饰的方法,需要创建对象后才能调用,是因为实例方法中可能会访问实例变量,而实例变量需要创建对象后才存在。
10.1.5 static的注意事项
10.2 代码块(匿名、静态)
package com.oop.demo07;public class Person {//2:附初始值{System.out.println("匿名代码块"); //代码块(匿名代码块)}//1 只执行一次static {//代码块(静态代码块)System.out.println("静态代码块");}//3public Person() {System.out.println("构造方法");}public static void main(String[] args) {Person person1 = new Person();System.out.println("====================");Person person2 = new Person();}
}
10.2 单例设计模式
10.2.1 单例设计模式之饿汉式
单例设计模式(饿汉式)调用对象之前,对象已经创建好了
package com.sesameseed.p4_singleinstance;public class A {//TODO 单例设计模式(饿汉式)调用对象之前,对象已经创建好了//2.定义一个类变量记住一个对象private static A a = new A();//1.必须私有类的构造器private A(){}//3.定义一个类方法返回类的对象public static A getObject(){return a;}
}
10.2.2 单例设计模式之懒汉式
package com.sesameseed.p4_singleinstance;public class B {//TODO 单例设计模式(懒汉式)第一次调用对象时,才开始创建对象//2.定义一个类变量,用于存放这个类的一个对象private static B b; //默认值null// 1.把类的构造器私有private B(){}// 3.定义一个类方法,这个方法保证第一次调用时才创建一次public static B getInstance(){if (b == null){b = new B();}return b;}
}
package com.sesameseed.p4_singleinstance;public class TestAB {public static void main(String[] args) {//TODO 掌握单例模式的写法(饿汉式、懒汉式)A a1 = A.getObject();A a2 = A.getObject();System.out.println(a1);System.out.println(a2);System.out.println("============");B b1 = B.getInstance();B b2 = B.getInstance();System.out.println(b1);System.out.println(b2);}
}
Day11: 面向对象高级二
11.1 多态
什么是多态?
- 多态是在继承、实现情况下的一种现象,表现为: 对象多态、行为多态
对象多态与行为多态:
本引用模块中Teacher和Student都是People的子类
- 对象多态
注意:
- 像这种父类变量接收子类对象的现象是 对象多态 ;
- p1和p2都是People类型,但是p1和p2指向的对象不一样,这种现象称之为对象多态
- 行为多态
注意:
- p1本质上代表学生对象,p2本质上代表老师对象
- p1和p2都可以调用run方法,但是两个run方法表现的行为不同,这种现象就认为是: 行为多态
11.2 多态优点
多态形式下,右边的代码是解耦合的,更便于扩展和维护
- 内聚与耦合
内聚是指一个模块内的交互程度,耦合是指模块间的交互程度。我们需要尽力做到高内聚低耦合
多态优点概念引入
解释:刚开始p1指向Student对象,run执行Student对象的业务;假如p1指向Teacher对象 ,run方法执行Teacher对象的业务。
11.2.1 案例一
注意点:
构成多态的规则:
- 1.必须有继承、实现关系
- 2.必须有方法重写
- 3.必须有父类引用指向子类对象
- 4.多态访问变量时,编译看左,运行也看左
- 5.多态访问方法时,编译看左,运行看右
package com.sesameseed.d1_polymorphism;public class Peolple {String name = "父类";public void run(){System.out.println("人会跑");}
}
package com.sesameseed.d1_polymorphism;public class Student extends Peolple{String name = "学生";@Overridepublic void run() {System.out.println("学生跑的飞快");}public void study() {System.out.println("学生学习");}
}
package com.sesameseed.d1_polymorphism;public class Teacher extends Peolple{String name = "老师";@Overridepublic void run() { //重写快捷键,重写的方法名+enter键System.out.println("老师跑得慢");}public void teach(){System.out.println("老师教书");}
}
package com.sesameseed.d1_polymorphism;public class Test {//TODO 认识多态/** 构成多态的规则:* 1.必须有继承、实现关系* 2.必须有方法重写* 3.必须有父类引用指向子类对象* */public static void main(String[] args) {//多态访问变量时,编译看左,运行也看左Peolple p1 = new Teacher();System.out.println(p1.name);//多态访问方法时,编译看左,运行看右p1.run();Peolple p2 = new Student();System.out.println(p2.name);p2.run();}
}
package com.sesameseed.d1_polymorphism.demo1;public class Test2 {public static void main(String[] args) {/* TODO 使用多态的好处,以及多态下的类型转换问题多态好处 耦合性低,扩展性强弊端 不能调用子类独有的方法*/Teacher t = new Teacher();go(t);}public static void go(Peolple p){ //底层变成多态样子:People p = new Teacher();System.out.println("==开始==");p.run();/* p.teach();p.study();//两个方法在多态形式下是不能直接调用*/if (p instanceof Student){Student s = (Student) p;s.study();}else if (p instanceof Teacher){Teacher t = (Teacher) p;t.teach();}
// 关于多态转型问题:原本是什么类型,才能还原成什么类型}
}
11.3 final关键字
final关键字是最终的意思
- final修饰类:该类称为最终类,特点是不能被继承
- final修饰方法:该方法称之为最终方法,特点是不能被重写。
- final修饰变量:该变量只能被赋值一次。
11.3.1 案例一
package com.sesameseed.d4_finaldemo;final class A { }
//class B extends A{}//Cannot inherit from final 'com.sesameseed.d4_finaldemo.A' ,修饰符,类不能被继承了
11.3.2 案例二
package com.sesameseed.d4_finaldemo;public class C {public final void test(){}
}class D extends C{/* @Overridepublic void test(){//test()' cannot override 'test()' in 'com.sesameseed.d4_finaldemo.C'; overridden method is final//不能重写C类的test方法,因为C类的test方法被final修饰}*/
}
11.3.3 案例二
package com.sesameseed.d4_finaldemo;public class FinalDemo1 {public static void main(String[] args) {//目标 :掌握final关键字的基本作用//变量有几种? 局部变量,成员变量(类变量,实例变量)final double a = 3.14;
// a = 3.15;Cannot assign a value to final variable 'a' 不能再给a赋值,因为a是被final修饰的final int[] arr1 = {10, 20, 30};
// arr1 = null; //Cannot assign a value to final variable 'arr1' 不能给final修饰arr1变量赋值arr1[1] = 222;}
}
11.4 抽象类
- 1.认识一下什么是抽象类
在Java中有一个关键字叫abstract,它就是抽象的意思,它可以修饰类也可以修饰方法
- 被abstract修饰的类,就是抽象类
- 被abstract修饰的方法,就是抽象方法(不允许有方法体)
- 2.认识一下什么是抽象类
- 抽象类中可以不写抽象方法,但有抽象方法的类一定是抽象类
- 类有的成员(成员变量、方法、构造器),抽象类都具备。
- 抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
- 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
11.4.1 案例一
package com.oop.demo08;//abstract 抽象类关键字 extends:只能单继承,接口(interface)可以多继承
public abstract class Action {//约束~有人帮我们实现//abstract , 抽象方法,只有方法的名字,没有方法的实现public abstract void doSomething();/*抽象类特点1.不能new这个抽象类,只能靠子类去实现它:约束2.抽象类中可以写普通方法3.抽象方法必须写在抽象类中4.抽象的抽象:就是一个约束*///思考题? new ,里面是否存在构造器?//存在意义 抽象出来一些要重复的东西,提高开发效率}
11.4.2 案例二
package com.sesameseed.d2_abstract.demo2;//abstract修饰类,这个类就是抽象类
public abstract class A {private String name;static String schoolName;//构造方法public A() {}public String getName() {return name;}public void setName(String name) {this.name = name;}//实例方法public static String getSchoolName() {return schoolName;}public static void setSchoolName(String schoolName) {A.schoolName = schoolName;}//abstract修饰方法,这个方法就是抽象方法public abstract void test();
}
package com.sesameseed.d2_abstract.demo2;public class B extends A{//TODO 抽象类虽然不能创建对象,但是它可以作为父类让子类继承。而且子类继承父类必须重写父类的所有抽象方法。
//B类继承A类,必须复写test方法@Overridepublic void test() {}
}
package com.sesameseed.d2_abstract.demo2;//TODO 子类继承父类如果不复写父类的抽象方法,要想不出错,这个子类也必须是抽象类
public abstract class C extends A{//B类基础A类,此时B类也是抽象类,这个时候就可以不重写A类的抽象方法
}
package com.sesameseed.d2_abstract.demo2;public class Test {public static void main(String[] args) {//抽象类是不能创建对象的,如果抽象类的对象就
// A a = new A();A' is abstract; cannot be instantiated
// a.test();}
}
11.4.3 案例三
注意:在此案例中,每种动物都有其独特的叫声,因此将父类Animal定义成抽象类,这样的好处就是利用抽象类的子类必须被重写的特点满足各场景使用需求。
package com.sesameseed.d2_abstract.demo1;public abstract class Animal {private String name;//动物叫的行为:不具体,是抽象的public abstract void cry();public String getName() {return name;}public void setName(String name) {this.name = name;}
}
package com.sesameseed.d2_abstract.demo1;public class Cat extends Animal{@Overridepublic void cry() {System.out.println(getName() + "喵喵喵");}
}
package com.sesameseed.d2_abstract.demo1;public class Dog extends Animal{public void cry(){System.out.println(getName() + "汪汪汪");}
}
package com.sesameseed.d2_abstract.demo1;public class Pig extends Animal{@Overridepublic void cry() {System.out.println(getName() + "嚯嚯嚯");}
}
package com.sesameseed.d2_abstract.demo1;public class Test2 {public static void main(String[] args) {/* TODO 掌握抽象类的使用场景和好处应用场景1.先写父类,让子类继承,拓展性更好2.先写子类,抽取共性内容到父类,代码更灵活* 多态三种方式1.具体类多态(所继承父类方法时普通书写类型)2.抽象类多态应用场景选择注意点:必须 抽象,不是必须 普通* */Animal a = new Pig();a.cry();}
}
11.5 设计模式——模板方法模式
- 设计模式:是解决某一类问题的最优方案
- 模板方法模式主要解决方法中存在重复代码的问题
11.5.1 案例一
注意:此案例中AB都会有
System.out.println("唱一首你喜欢的歌");
此类的重复代码,因此我们将此类重复代码封装在一个方法中,利用模板设计模式减少重复代码。
package com.sesameseed.p3_abstract_template;//模板方法设计模式
public abstract class C {//模板方法public final void sing(){System.out.println("唱一首你喜欢的歌");doSing();System.out.println("唱完了");}public abstract void doSing();
}
package com.sesameseed.p3_abstract_template;public class A extends C{@Overridepublic void doSing() {System.out.println("我们唱p2");}
}
package com.sesameseed .p3_abstract_template;public class B extends C{@Overridepublic void doSing() {System.out.println("我们唱P1");}
}
package com.sesameseed.p3_abstract_template;public class Test {public static void main(String[] args) {//TODO 设计模式解决什么问题,以及怎么写B b = new B();b.sing();}
}
11.6 接口
- Java提供了一个关键字interface,可以定义出一个特殊的结构: 接口。
public interface 接口名{// 成员变量(常量)
// 成员方法(抽急方法
}
注意:
- 接口不能创建对象;接口是用来被类实现( implements)的,实现接口的类称为实现类修饰符 class 实现类
- 实现类实现多个接口,必须重写完全部接口的全部推象方法,或者实现类需要定义成抽象类。
implements 接口1,接口2,接口3,..[
一个类可以实现多个接口(接口可以理解成干爹)
11.6.1 案例一
package com.oop.demo09;//抽象的思维
//interface 定义的关键字,接口都需要有现实类 命名都需要以Impl结尾
public interface UserService {//常量 public static finalpublic static final int AGE = 99;//接口中所有定义其实都是抽象的 public abstractpublic abstract void add(String name);void delete(String name);void update(String name);void query(String name);
}对应的现实类
package com.oop.demo09;//抽象类 extends
//类 可以实现接口 implements 接口
//实现了接口的类,就需要重写接口中的方法 (ALT + INS -> Override)//多继承 利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService{@Overridepublic void add(String name) {}@Overridepublic void delete(String name) {}@Overridepublic void update(String name) {}@Overridepublic void query(String name) {}@Overridepublic void timer() {}
}
接口作用:
1.接口就是一个约束
2.定义一个方法,让不同的人实现
3.方法都是 public static
4.常量都是public static final
5.接口不能实例化,接口中没有构造方法
6.implements可以实现多个接口
7.必须要重写接口中的方法(ALT + INS -> Override)
接口优点:
1.弥补了类单继承的不足,一个类同时可以实现多个接口
2.让程序可以面向接口编程,这样可以灵活切换各种业务实现.
11.6.2 案例二
注意:
- 接口是不能创建对象的
- 接口使用implements类实现,然后就可以再newi一个mplements类对象实现所需方法,
package com.sesameseed.d5_interfacedemo.demo1;public interface A {//这里public static final可以加,可以不加。
// public static final String SCHOOL_NAME = "家里蹲";String SCHOOL_NAME = "家里蹲";
}
package com.sesameseed.d5_interfacedemo.demo1;public interface B {void testb1();void testb2();
}
package com.sesameseed.d5_interfacedemo.demo1;public interface C {void testc1();void testc2();
}
package com.sesameseed.d5_interfacedemo.demo1;public class D implements B,C{//实现类D,同时实现B接口和C接口,此时就需要复写四个方法,如下代码@Overridepublic void testc1() {}@Overridepublic void testc2() {}@Overridepublic void testb1() {}@Overridepublic void testb2() {}
}
package com.sesameseed.d5_interfacedemo.demo1;public class Test {public static void main(String[] args) {//打印A接口中的常量System.out.println(A.SCHOOL_NAME);接口是不能创建对象的
// A a = new A();'A' is abstract; cannot be instantiated// D类是接口的实现类,对D类创建对象D d = new D();}
}
Day12: 面向对象高级三
12.1 内部类
12.1.1 成员内部类
成员内部类就是类中的一个普通成员,类似于成员变量、成员方法。
10.2.1.1 成员内部类案例
package com.sesameseed.d1_inner.peopleinner;public class Outer {private int age = 99;public static String a = "李明";public int getAge() {return age;}public void setAge(int age) {this.age = age;}public static String getA() {return a;}public static void setA(String a) {Outer.a = a;}// 成员内部类public class Inner{private String name;private int age = 88;// 在内部类中既可以访问自己类的成员,也可以访问外部类的成员public void test(){System.out.println(age); //88System.out.println(a); //李明int age = 77;System.out.println(age); //77System.out.println(this.age); //88System.out.println(Outer.this.age);//99}}
}
package com.sesameseed.d1_inner.peopleinner;public class Test {public static void main(String[] args) {//外部类.内部类 变量名 = new 外部类().new 内部类();Outer.Inner inner = new Outer().new Inner();//调用内部类的方法inner.test();}
}
12.2.2 静态内部类
成员内部类的前面加了一个static关键字。静态内部类属于外部类自己持有
12.2.2.1 静态内部类案例
package com.sesameseed.d1_inner.staticinner;public class Outer {private int age = 90;public static String schoolName = "家里蹲";// 静态内部类public static class Inner{public void test(){System.out.println(schoolName);//静态内部类访问外部类的静态变量,是可以的;
// System.out.println(age); //报错 静态内部类访问外部类的实例变量,是不行的}}}
package com.sesameseed.d1_inner.staticinner;public class Test {public static void main(String[] args) {//格式:外部类.内部类 变量名 = new 外部类.内部类();Outer.Inner inner = new Outer.Inner();inner.test();}
}
12.2.3 局部内部类
定义在方法中的类,和局部变量一样,只能在方法中有效。局限性很强,一般在开发中是不会使用的。
12.2.3.1 局部内部类案例
package com.sesameseed.d1_inner.partinner;public class Outer {public void test(){//局部内部类class Inner{public void show(){System.out.println("partInner");}}//局部内部类只能在方法中创建对象,并使用Inner inner = new Inner();inner.show();}
}
package com.sesameseed.d1_inner.partinner;public class Test {public static void main(String[] args) {//new对象调用Outer outer = new Outer();outer.test();}
}
12.2.4 匿名内部类
是一种特殊的局部内部类;所谓匿名,指不需要类声明名字。
new 父类/接口(参数值){@Override重写父类/接口的方法;
}
12.2.4.1 匿名内部类案例
package com.sesameseed.d1_inner.anonymousinner;//继承单继承,实现多实现
/*
实现法比较:1.普通方法:每一个都要做个类,代码冗余2.抽象类继承方法:由于继承单继承,只能实现继承一个方法,抽象类虽然必须重写方法,但是如果想继承实现父类多个方法,又不行了3.接口实现:接口实现可以多实现,就可以实现父类中多个方法,同时实现类中也必须重写接口类中方法,所以后期可扩展高,适用于动物会游泳,后期他会跑也行,此业务
*/
public interface Swimming {// public abstract void swim();void swim(); //public abstract默认有
}
package com.sesameseed.d1_inner.anonymousinner;public class Test {public static void main(String[] args) {//这里后面new 的部分,其实就是一个Swimming的子类对象//这里隐含的有多态的特性: Swimming swimming = Swimming子类对象;//第一种书写方法Swimming swimming = new Swimming(){@Overridepublic void swim() {System.out.println("猫游泳1");}};go(swimming);//匿名内部类规范写法go(new Swimming(){@Overridepublic void swim() {System.out.println("猪会游泳2");}});}public static void go(Swimming swimming){swimming.swim();}
}
12.3 枚举
枚举是一种特殊的类,它的格式是:
public enum 枚举类名{枚举项1,枚举项2,枚举项3;
}
12.3.1 枚举案例
package com.sesameseed.d2_enumdemo;public enum Constant {//Enum:应用场景,用来表示一组信息,进行传参
// public static final int BOY = 0;
// public static final int GIRL = 1;BOY, GIRL;
}
package com.sesameseed.d2_enumdemo;public class Test {public static void main(String[] args) {//目标: 掌握枚举的使用场景}public static void printdeIndo(Constant sex){switch (sex){case BOY:System.out.println("男生");break;case GIRL:System.out.println("男生");break;}}
}
12.4 泛型
- 泛型的好处:在编译阶段可以避免出现一些非法的数据。
- 泛型的本质:把具体的数据类型传递给类型变量。
12.5 常用API
12.5.1 Object类
Object类是Java中所有类的祖宗类,因此,Java中所有类的对象都可以直接使用Object类中提供的一些方法。
package com.sesameseed.d6_api_object;public class Student {private String name;private int age;//Object中equals比较地址值,重写equals比较内容@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return name != null ? name.equals(student.name) : student.name == null;}// @Override
// public int hashCode() {// int result = name != null ? name.hashCode() : 0;
// result = 31 * result + age;
// return result;
// }//Object中toString返回地址值,重写toString方法返回字符串内容@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}
}
package com.sesameseed.d6_api_object;public class Test {public static void main(String[] args) {//目标:掌握object类提供的常用方法Student student = new Student("李明",20);
// System.out.println(student.toString()); 默认调用toStringSystem.out.println(student);Student student1 = new Student("李明",20);System.out.println(student1.equals(student));}
}
12.5.2 基本类型包装类
Java中的8种基本数据类型还不是对象,所以要把它们变成对象,变成对象之后,可以提供一些方法对数据进行操作。
- 创建包装类的对象方式、自动装箱和拆箱的特性;
- 利用包装类提供的方法对字符串和基本类型数据进行相互转换
package com.sesameseed.d7_wrapperclass;public class Test {public static void main(String[] args) {//目标:掌握包装类的使用//自动装箱:可以自动把基本类型的数据转换成对象int a1 = 12;Integer a2 = a1;Character c1 = 'a';
// System.out.println(c1 instanceof String);//自动拆箱:可以自动把包装类类型的对象转换成对应的基本数据类型int a3 = a2;System.out.println("===========");//基本类型 -->字符串int ii = 22;//方式一String s1 = Integer.toString(ii);System.out.println("s1是" + s1);//方式二String s2 = ii + "";System.out.println("s2是" + s2);System.out.println("s2是String:" + s2 instanceof String); //true//字符串 -->基本类型String ss = "111";//方式一int i = Integer.parseInt(ss);System.out.println("i是" + i);//方式二Integer i2 = Integer.valueOf(ss);System.out.println("i2是" + i2);System.out.println("i2是Integer:" + (i2 instanceof Integer)); //true}
}
//1.创建Integer对象,封装基本类型数据10
Integer a = new Integer(10);//2.使用Integer类的静态方法valueOf(数据)
Integer b = Integer.valueOf(10);//3.还有一种自动装箱的写法(意思就是自动将基本类型转换为引用类型)
Integer c = 10;//4.有装箱肯定还有拆箱(意思就是自动将引用类型转换为基本类型)
int d = c;//5.装箱和拆箱在使用集合时就有体现
ArrayList<Integer> list = new ArrayList<>();
//添加的元素是基本类型,实际上会自动装箱为Integer类型
list.add(100);
//获取元素时,会将Integer类型自动拆箱为int类型
int e = list.get(0);
Day13: 常用API
13.1 StringBuilder与StringBuffer类
StringBuilder代表可变字符串对象,是线程不安全的。相当于是一个容器,它里面的字符串是可以改变的,就是用来操作字符串的。
StringBuilder的效率比String更高
理由:string用+号做拼接,拼接底层会进行new对象操作。
package com.sesameseed.d1_stringbuild;public class Test {public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder();System.out.println("###" + stringBuilder + "@@@@");//###@@@@StringBuilder stringBuilder1 = new StringBuilder();System.out.println(stringBuilder1); //111cdetrue//拼接字符串,追加//链式编程stringBuilder.append(111).append("cde").append(true);System.out.println(stringBuilder);//2.反转字符stringBuilder.reverse();System.out.println(stringBuilder);//eurtedc111//3.长度int lenght = stringBuilder.length();System.out.println(lenght);//10//4.stringBuilder转StringString s = stringBuilder.toString(); //eurtedc111System.out.println(s);}
}
package com.sesameseed.d1_stringbuild;public class Test2 {public static void main(String[] args) {int[] arr ={11, 22, 33, 44};
// arr = null; 如果数组为空校验测试System.out.print(getArrContent(arr));System.out.print("]");}//拼接数组内容并返回public static String getArrContent(int[] arr){//加参数的非法校验if (arr == null){return null;}StringBuilder stringBuilder = new StringBuilder();
// stringBuilder.append("[");System.out.print("[");for (int i = 0; i < arr.length; i++) {//判断如果是最后一个树,不拼接“,”号if (arr[i] == arr[arr.length-1]){stringBuilder.append(arr[i]);}else {stringBuilder.append(arr[i]).append(",");}}
// stringBuilder.append("]");
// System.out.print("]");return stringBuilder.toString();}
}
StringBuffer是线程安全的,因为底层都加了synchronized关键字(线程同步锁),确保线程安全
public class Demo {public static void main(String[] args) {StringBuffer sbf = new StringBuffer("班金莲");;//线程安全的 效率低 1,同样的代码,同一时刻只能被一个线程执行StringBuffer sbf1 = sbf;sbf.append("爱大朗");System.out.println(sbf);//班金莲爱大朗System.out.println(sbf1);//班金莲爱大朗System.out.println(sbf == sbf1);//true}
}
13.2 Math类
Math是数学的意思,该类提供了很多个进行数学运算的方法,如求绝对值,求最大值,四舍五入等
package com.sesameseed.d2_math;public class Test {public static void main(String[] args) {// 1、public static int abs(int a):取绝对值(拿到的结果一定是正数)System.out.println(Math.abs(-12)); // 12System.out.println(Math.abs(123)); //123System.out.println(Math.abs(-3.14)); //3.14// 2、public static double ceil(double a): 向上取整System.out.println(Math.ceil(4.00001)); //5.0System.out.println(Math.ceil(4.0)); //4.0// 3、public static double floor(double a): 向下取整System.out.println(Math.floor(4.99999)); //5.0System.out.println(Math.floor(4.0)); //4.0// 4、public static long round(double a):四舍五入System.out.println(Math.round(4.99999)); //5System.out.println(Math.round(4.0)); //4// 5、public static int max(int a, int b):取较大值// public static int min(int a, int b):取较小值System.out.println(Math.max(10,20)); //20System.out.println(Math.min(10,20)); //10// 6、 public static double pow(double a, double b):取次方System.out.println(Math.pow(2,3));System.out.println(Math.pow(3,2));// 7、public static double random(): 取随机数 [0.0 , 1.0) (包前不包后)System.out.println(Math.random());}
}
13.3 System类
这是系统类,提供了一些获取获取系统数据的方法。比如获取系统时间
package com.sesameseed.d2_math;public class Test2 {public static void main(String[] args) {// 1、public static void exit(int status):
// 终止当前运行的Java虚拟机。
// 该参数用作状态代码; 按照惯例,非零状态代码表示异常终止。
// System.exit(0);// public static long currentTimeMillis():
// 获取当前系统的时间
// 返回的是long类型的时间毫秒值:指的是从1970-1-1 0:0:0开始走到此刻的总的毫秒值,1s = 1000mslong time = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {System.out.println("输出了:" + i);}long time2 = System.currentTimeMillis();System.out.println((time2 - time) / 1000.0 + "s");}
}
13.4 Runtime类
这个类可以用来获取JVM的一些信息,也可以用这个类去执行其他的程序
package com.sesameseed.d3_runtime;import java.io.IOException;public class RuntimeTest {public static void main(String[] args) throws IOException, InterruptedException {// 1、public static Runtime getRuntime() 返回与当前Java应用程序关联的运行时对象。Runtime runtime = Runtime.getRuntime();
// System.out.println(runtime);// 2、public void exit(int status) 终止当前运行的虚拟机,该参数用作状态代码; 按照惯例,非零状态代码表示异常终止。
// runtime.exit(0);// 3、public int availableProcessors(): 获取虚拟机能够使用的处理器数。System.out.println(runtime.availableProcessors());// 4、public long totalMemory() 返回Java虚拟机中的内存总量。System.out.println(runtime.totalMemory());// 5、public long freeMemory() 返回Java虚拟机中的可用内存量System.out.println(runtime.freeMemory());// 6、public Process exec(String command) 启动某个程序,并返回代表该程序的对象。Process p = runtime.exec("C:\\Users\\jiaoxin\\Desktop\\FeiQ.exe");Thread.sleep(5000); //让程序在这里暂停5000/1000 = 5 s后继续走p.destroy();}
}
13.5 BigDecimal类
解决计算精度损失的问题,Java给我们提供了BigDecimal类
package com.sesameseed.d4_bigdecimal;import java.math.BigDecimal;
import java.math.RoundingMode;public class Test {public static void main(String[] args) {//目标 掌握BigDecimal进行精确运算的方案double a = 0.1;double b = 0.2;//1.把浮点型数据封装成BigDecimal对象,再来参与运算// a、public BigDecimal(double val) 得到的BigDecimal对象是无法精确计算浮点型数据的。 注意:不推荐使用这个BigDecimal bigDecimal1 = new BigDecimal(0.2); //不建议使用 输出:bigDecimal10.200000000000000011102230246251565404236316680908203125System.out.println("bigDecimal1" + bigDecimal1);// b、public BigDecimal(String val) 得到的BigDecimal对象是可以精确计算浮点型数据的。 可以使用。// c、public static BigDecimal valueOf(double val): 通过这个静态方法得到的BigDecimal对象是可以精确运算的。是最好的方案。BigDecimal bigDecimal = BigDecimal.valueOf(a);BigDecimal b1 = BigDecimal.valueOf(b);// 2、public BigDecimal add(BigDecimal augend): 加法BigDecimal add = bigDecimal.add(b1);System.out.println(add); //0.3// 3、public BigDecimal subtract(BigDecimal augend): 减法BigDecimal subtract = bigDecimal.subtract(b1);System.out.println(subtract); //-0.1// 4、public BigDecimal multiply(BigDecimal augend): 乘法BigDecimal multiply = bigDecimal.multiply(b1);System.out.println(multiply); //0.02// 5、public BigDecimal divide(BigDecimal b): 除法BigDecimal divide = bigDecimal.divide(b1);System.out.println(divide); //0.5// BigDecimal bigDecimal2 = BigDecimal.valueOf(0.1);
// BigDecimal bigDecimal3 = BigDecimal.valueOf(0.3);
// BigDecimal divide1 = bigDecimal2.divide(bigDecimal3);
// System.out.println(divide1); //ArithmeticException 返回的值是循环的 bigdecial返回值得是精确地// 6、public BigDecimal divide(另一个BigDecimal对象,精确几位,舍入模式) : 除法,可以设置精确几位。BigDecimal bigDecimal2 = BigDecimal.valueOf(0.1);BigDecimal bigDecimal3 = BigDecimal.valueOf(0.3);BigDecimal divide1 = bigDecimal2.divide(bigDecimal3, 2, RoundingMode.HALF_UP);//四舍五入System.out.println("结果" + divide1);// 7、public double doubleValue() : 把BigDecimal对象又转换成double类型的数据。double v = bigDecimal3.doubleValue();double v1 = bigDecimal2.doubleValue();print(v);print(v1);}public static void print(double a){System.out.println(a);}
}
13.6 Date类
学习一下Date类,Java中是由这个类的对象用来表示日期或者时间。
Date对象记录的时间是用毫秒值来表示的。Java语言规定,1970年1月1日0时0分0秒认为是时间的起点,此时记作0,那么1000(1秒=1000毫秒)就表示1970年1月1日0时0分1秒,依次内推。
public class Test1Date {public static void main(String[] args) {// 目标:掌握Date日期类的使用。// 1、创建一个Date的对象:代表系统当前时间信息的。Date d = new Date();System.out.println(d);// 2、拿到时间毫秒值。long time = d.getTime();System.out.println(time);// 3、把时间毫秒值转换成日期对象: 2s之后的时间是多少。time += 2 * 1000;Date d2 = new Date(time);System.out.println(d2);// 4、直接把日期对象的时间通过setTime方法进行修改Date d3 = new Date();d3.setTime(time);System.out.println(d3);}
}
13.7 SimpleDateFormat类
SimpleDateFormat类就可以转换Date对象表示日期时间的显示格式
- 我们把Date对象转换为指定格式的日期字符串这个操作,叫做日期格式化,
- 反过来把指定格式的日期符串转换为Date对象的操作,叫做日期解析。
常用的几种日期/时间格式
字母 表示含义
yyyy 年
MM 月
dd 日
HH 时
mm 分
ss 秒
SSS 毫秒
案例一:
package com.sesameseed.d5_time;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;public class Test2SimpleDateFormat {//目标:掌握SimpleDateFormat的使用public static void main(String[] args) throws ParseException {//1.准备一个时间Date date = new Date();System.out.println("i am here :" + date);//2.格式化日期对象 时间 毫秒值SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");String timeFormat = simpleDateFormat.format(date);System.out.println(timeFormat);System.out.println("-------------");//String -> Date//目标 掌握SimpleDateFormat解析字符串时间 成为日期对象String dateStr = "2023-1-6 15:26:26";//1.创建日期格式化对象,指定的时间格式必须与被解析的时间格式一模一样,否则会出bugSimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date timeParse = simpleDateFormat1.parse(dateStr);System.out.println(timeParse);}
}
案例二:
package com.sesameseed.d5_time;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;public class SaleDemo {public static void main(String[] args) throws ParseException {/*目标 完成秒杀判定案例做时间计算,将string转data 转long做时间展示:将long 转Date 转 String* *///1.把开始时间 结束时间 小贾 小皮下单时间 拿到程序中String start = "2023年11月11日 0:0:0";String end = "2023年11月11日 0:10:0";String xj = "2023年11月11日 0:01:18";String xp = "2023年11月11日 0:10:57";//2.把字符串的时间解析成日期对象SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");Date starParse = simpleDateFormat.parse(start);Date endParse = simpleDateFormat.parse(end);Date xjParse = simpleDateFormat.parse(xj);Date xpParse = simpleDateFormat.parse(xp);//3.开始判断小皮小贾是否秒杀成功//把日期对象转换成时间毫秒值long starTime = starParse.getTime();long endTime = endParse.getTime();long xjTime = xjParse.getTime();long xpTime = xpParse.getTime();//逻辑判断if (xjTime >= starTime && xjTime <= endTime){System.out.println("小贾成功");}else {System.out.println("小贾失败");}if (xpTime >= starTime && xpTime <= endTime){System.out.println("小皮成功");}else {System.out.println("小皮失败");}}
}
13.8 Calendar类
Calendar类表示日历,它提供了一些比Date类更好用的方法。
public class Test4Calendar {public static void main(String[] args) {// 目标:掌握Calendar的使用和特点。// 1、得到系统此刻时间对应的日历对象。Calendar now = Calendar.getInstance();System.out.println(now);// 2、获取日历中的某个信息int year = now.get(Calendar.YEAR);System.out.println(year);int days = now.get(Calendar.DAY_OF_YEAR);System.out.println(days);// 3、拿到日历中记录的日期对象。Date d = now.getTime();System.out.println(d);// 4、拿到时间毫秒值long time = now.getTimeInMillis();System.out.println(time);// 5、修改日历中的某个信息now.set(Calendar.MONTH, 9); // 修改月份成为10月份。now.set(Calendar.DAY_OF_YEAR, 125); // 修改成一年中的第125天。System.out.println(now);// 6、为某个信息增加或者减少多少now.add(Calendar.DAY_OF_YEAR, 100);now.add(Calendar.DAY_OF_YEAR, -10);now.add(Calendar.DAY_OF_MONTH, 6);now.add(Calendar.HOUR, 12);now.set(2026, 11, 22);System.out.println(now);}
}
13.9 JDK8日期、时间、日期时间
为什么以前的Date类就可以表示日期,为什么要有新增的日期类呢?
13.9.1 LocalDate类
public class Test1_LocalDate {public static void main(String[] args) {// 0、获取本地日期对象(不可变对象)LocalDate ld = LocalDate.now(); // 年 月 日System.out.println(ld);// 1、获取日期对象中的信息int year = ld.getYear(); // 年int month = ld.getMonthValue(); // 月(1-12)int day = ld.getDayOfMonth(); // 日int dayOfYear = ld.getDayOfYear(); // 一年中的第几天int dayOfWeek = ld.getDayOfWeek().getValue(); // 星期几System.out.println(year);System.out.println(day);System.out.println(dayOfWeek);// 2、直接修改某个信息: withYear、withMonth、withDayOfMonth、withDayOfYearLocalDate ld2 = ld.withYear(2099);LocalDate ld3 = ld.withMonth(12);System.out.println(ld2);System.out.println(ld3);System.out.println(ld);// 3、把某个信息加多少: plusYears、plusMonths、plusDays、plusWeeksLocalDate ld4 = ld.plusYears(2);LocalDate ld5 = ld.plusMonths(2);// 4、把某个信息减多少:minusYears、minusMonths、minusDays、minusWeeksLocalDate ld6 = ld.minusYears(2);LocalDate ld7 = ld.minusMonths(2);// 5、获取指定日期的LocalDate对象: public static LocalDate of(int year, int month, int dayOfMonth)LocalDate ld8 = LocalDate.of(2099, 12, 12);LocalDate ld9 = LocalDate.of(2099, 12, 12);// 6、判断2个日期对象,是否相等,在前还是在后: equals isBefore isAfterSystem.out.println(ld8.equals(ld9));// trueSystem.out.println(ld8.isAfter(ld)); // trueSystem.out.println(ld8.isBefore(ld)); // false}
}
13.9.2 LocalTime类
public class Test2_LocalTime {public static void main(String[] args) {// 0、获取本地时间对象LocalTime lt = LocalTime.now(); // 时 分 秒 纳秒 不可变的System.out.println(lt);// 1、获取时间中的信息int hour = lt.getHour(); //时int minute = lt.getMinute(); //分int second = lt.getSecond(); //秒int nano = lt.getNano(); //纳秒// 2、修改时间:withHour、withMinute、withSecond、withNanoLocalTime lt3 = lt.withHour(10);LocalTime lt4 = lt.withMinute(10);LocalTime lt5 = lt.withSecond(10);LocalTime lt6 = lt.withNano(10);// 3、加多少:plusHours、plusMinutes、plusSeconds、plusNanosLocalTime lt7 = lt.plusHours(10);LocalTime lt8 = lt.plusMinutes(10);LocalTime lt9 = lt.plusSeconds(10);LocalTime lt10 = lt.plusNanos(10);// 4、减多少:minusHours、minusMinutes、minusSeconds、minusNanosLocalTime lt11 = lt.minusHours(10);LocalTime lt12 = lt.minusMinutes(10);LocalTime lt13 = lt.minusSeconds(10);LocalTime lt14 = lt.minusNanos(10);// 5、获取指定时间的LocalTime对象:// public static LocalTime of(int hour, int minute, int second)LocalTime lt15 = LocalTime.of(12, 12, 12);LocalTime lt16 = LocalTime.of(12, 12, 12);// 6、判断2个时间对象,是否相等,在前还是在后: equals isBefore isAfterSystem.out.println(lt15.equals(lt16)); // trueSystem.out.println(lt15.isAfter(lt)); // falseSystem.out.println(lt15.isBefore(lt)); // true}
}
13.9.3 LocalDateTime类
public class Test3_LocalDateTime {public static void main(String[] args) {// 0、获取本地日期和时间对象。LocalDateTime ldt = LocalDateTime.now(); // 年 月 日 时 分 秒 纳秒System.out.println(ldt);// 1、可以获取日期和时间的全部信息int year = ldt.getYear(); // 年int month = ldt.getMonthValue(); // 月int day = ldt.getDayOfMonth(); // 日int dayOfYear = ldt.getDayOfYear(); // 一年中的第几天int dayOfWeek = ldt.getDayOfWeek().getValue(); // 获取是周几int hour = ldt.getHour(); //时int minute = ldt.getMinute(); //分int second = ldt.getSecond(); //秒int nano = ldt.getNano(); //纳秒// 2、修改时间信息:// withYear withMonth withDayOfMonth withDayOfYear withHour// withMinute withSecond withNanoLocalDateTime ldt2 = ldt.withYear(2029);LocalDateTime ldt3 = ldt.withMinute(59);// 3、加多少:// plusYears plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanosLocalDateTime ldt4 = ldt.plusYears(2);LocalDateTime ldt5 = ldt.plusMinutes(3);// 4、减多少:// minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNanosLocalDateTime ldt6 = ldt.minusYears(2);LocalDateTime ldt7 = ldt.minusMinutes(3);// 5、获取指定日期和时间的LocalDateTime对象:// public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour,// int minute, int second, int nanoOfSecond)LocalDateTime ldt8 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);LocalDateTime ldt9 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);// 6、 判断2个日期、时间对象,是否相等,在前还是在后: equals、isBefore、isAfterSystem.out.println(ldt9.equals(ldt8));System.out.println(ldt9.isAfter(ldt));System.out.println(ldt9.isBefore(ldt));// 7、可以把LocalDateTime转换成LocalDate和LocalTime// public LocalDate toLocalDate()// public LocalTime toLocalTime()// public static LocalDateTime of(LocalDate date, LocalTime time)LocalDate ld = ldt.toLocalDate();LocalTime lt = ldt.toLocalTime();LocalDateTime ldt10 = LocalDateTime.of(ld, lt);}
}
13.10 JDK8日期(时区)
public class Test4_ZoneId_ZonedDateTime {public static void main(String[] args) {// 目标:了解时区和带时区的时间。// 1、ZoneId的常见方法:// public static ZoneId systemDefault(): 获取系统默认的时区ZoneId zoneId = ZoneId.systemDefault();System.out.println(zoneId.getId());System.out.println(zoneId);// public static Set<String> getAvailableZoneIds(): 获取Java支持的全部时区IdSystem.out.println(ZoneId.getAvailableZoneIds());// public static ZoneId of(String zoneId) : 把某个时区id封装成ZoneId对象。ZoneId zoneId1 = ZoneId.of("America/New_York");// 2、ZonedDateTime:带时区的时间。// public static ZonedDateTime now(ZoneId zone): 获取某个时区的ZonedDateTime对象。ZonedDateTime now = ZonedDateTime.now(zoneId1);System.out.println(now);// 世界标准时间了ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());System.out.println(now1);// public static ZonedDateTime now():获取系统默认时区的ZonedDateTime对象ZonedDateTime now2 = ZonedDateTime.now();System.out.println(now2);// Calendar instance = Calendar.getInstance(TimeZone.getTimeZone(zoneId1));}
}
13.11 JDK8日期(Instant类)
通过获取Instant的对象可以拿到此刻的时间,该时间由两部分组成:从1970-01-01 00:00:00 开始走到此刻的总秒数+不够1秒的纳秒数
作用:可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点。
/*** 目标:掌握Instant的使用。*/
public class Test5_Instant {public static void main(String[] args) {// 1、创建Instant的对象,获取此刻时间信息Instant now = Instant.now(); // 不可变对象// 2、获取总秒数long second = now.getEpochSecond();System.out.println(second);// 3、不够1秒的纳秒数int nano = now.getNano();System.out.println(nano);System.out.println(now);Instant instant = now.plusNanos(111);// Instant对象的作用:做代码的性能分析,或者记录用户的操作时间点Instant now1 = Instant.now();// 代码执行。。。。Instant now2 = Instant.now();LocalDateTime l = LocalDateTime.now();}
}
13.12 JDK8日期(格式化器DateTimeFormater)
DateTimeFormater。它可以从来对日期进行格式化和解析。它代替了原来的SimpleDateFormat类
/*** 目标:掌握JDK 8新增的DateTimeFormatter格式化器的用法。*/
public class Test6_DateTimeFormatter {public static void main(String[] args) {// 1、创建一个日期时间格式化器对象出来。DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");// 2、对时间进行格式化LocalDateTime now = LocalDateTime.now();System.out.println(now);String rs = formatter.format(now); // 正向格式化System.out.println(rs);// 3、格式化时间,其实还有一种方案。String rs2 = now.format(formatter); // 反向格式化System.out.println(rs2);// 4、解析时间:解析时间一般使用LocalDateTime提供的解析方法来解析。String dateStr = "2029年12月12日 12:12:11";LocalDateTime ldt = LocalDateTime.parse(dateStr, formatter);System.out.println(ldt);}
}
13.13 JDK8日期(Period类和Duration类)
- 都用来对计算两个时间点的时间间隔
- 其中Period用来计算日期间隔(年、月、日),
- Duration用来计算时间间隔(时、分、秒、纳秒)
Period案例:
/*** 目标:掌握Period的作用:计算机两个日期相差的年数,月数、天数。*/
public class Test7_Period {public static void main(String[] args) {LocalDate start = LocalDate.of(2029, 8, 10);LocalDate end = LocalDate.of(2029, 12, 15);// 1、创建Period对象,封装两个日期对象。Period period = Period.between(start, end);// 2、通过period对象获取两个日期对象相差的信息。System.out.println(period.getYears());System.out.println(period.getMonths());System.out.println(period.getDays());}
}
Duration案例:
ublic class Test8_Duration {public static void main(String[] args) {LocalDateTime start = LocalDateTime.of(2025, 11, 11, 11, 10, 10);LocalDateTime end = LocalDateTime.of(2025, 11, 11, 11, 11, 11);// 1、得到Duration对象Duration duration = Duration.between(start, end);// 2、获取两个时间对象间隔的信息System.out.println(duration.toDays());// 间隔多少天System.out.println(duration.toHours());// 间隔多少小时System.out.println(duration.toMinutes());// 间隔多少分System.out.println(duration.toSeconds());// 间隔多少秒System.out.println(duration.toMillis());// 间隔多少毫秒System.out.println(duration.toNanos());// 间隔多少纳秒}
}
13.14 Arrays类
Arrays是操作数组的工具类,它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作
13.14 .1 Arrays基本使用
/*** 目标:掌握Arrays类的常用方法。*/
public class ArraysTest1 {public static void main(String[] args) {// 1、public static String toString(类型[] arr): 返回数组的内容int[] arr = {10, 20, 30, 40, 50, 60};System.out.println(Arrays.toString(arr));// 2、public static 类型[] copyOfRange(类型[] arr, 起始索引, 结束索引) :拷贝数组(指定范围,包前不包后)int[] arr2 = Arrays.copyOfRange(arr, 1, 4);System.out.println(Arrays.toString(arr2));// 3、public static copyOf(类型[] arr, int newLength):拷贝数组,可以指定新数组的长度。int[] arr3 = Arrays.copyOf(arr, 10);System.out.println(Arrays.toString(arr3));// 4、public static setAll(double[] array, IntToDoubleFunction generator):把数组中的原数据改为新数据又存进去。double[] prices = {99.8, 128, 100};// 0 1 2// 把所有的价格都打八折,然后又存进去。Arrays.setAll(prices, new IntToDoubleFunction() {@Overridepublic double applyAsDouble(int value) {// value = 0 1 2return prices[value] * 0.8;}});System.out.println(Arrays.toString(prices));// 5、public static void sort(类型[] arr):对数组进行排序(默认是升序排序)Arrays.sort(prices);System.out.println(Arrays.toString(prices));}
}
13.14.2 Arrays操作对象数组实现排序
- 排序方式1:让Student类实现Comparable接口,同时重写compareTo方法。Arrays的sort方法底层会根据compareTo方法的返回值是正数、负数、还是0来确定谁大、谁小、谁相等。
package com.sesameseed.d1_arrays;public class Student implements Comparable<Student>{private String name;private double height;private int age;/** /指定比较规则步骤:1、让比较的类,实现Comparable<Student>接口2、重写compareTo方法,指定排序规则// 正整数:将即将排序的对象O 放左边/* 负整数:将即将排序的对象0,放右边* 0:默认按额序依次放* */// this: 已经排好序的对象 0: 即将排序的对象public String getName() {return name;}public void setName(String name) {this.name = name;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Student() {}public Student(String name, double height, int age) {this.name = name;this.height = height;this.age = age;}@Overridepublic int compareTo(Student A) {return this.age - A.age; //升序}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", height=" + height +", age=" + age +'}';}
}
- 排序方式2:在调用
Arrays.sort(数组,Comparator比较器);
时,除了传递数组之外,传递一个Comparator比较器对象。Arrays的sort方法底层会根据Comparator比较器对象的compare方法方法的返回值是正数、负数、还是0来确定谁大、谁小、谁相等。
package com.sesameseed.d1_arrays;import java.util.Arrays;
import java.util.Comparator;
import java.util.function.ToDoubleFunction;import static java.util.Arrays.*;public class ArraysDemo {public static void main(String[] args) {//目标 堂握如何对数组中的对象进行排序。Student[] students = new Student[4];students[0] = new Student("蜘蛛精",169.5,23);students[1] = new Student("紫霞",163.8,26);students[2] = new Student("紫霞",163.8,26);students[3] = new Student("至尊宝",167.5,24);/*方式实现Comparable<Student>接口 和 方式二 匿名内部类Comparator比较器对象区别 :方式一必须在数组的元素类中,进行实现。方式二不需要修改数组的元素类,直接以匿名内部类的方式指定排序规则* *///对于int型数组会直接排序,为啥呢?因为底层会自动装箱为Integer//1、public static void sort(类型[] arr): 对数组进行排序sort(students);System.out.println(Arrays.toString(students));String[] arr1 = {"ca", "bv" , "aa"};/*当原本类中定义的的排序规不能满足我们的需求时需要使用排序规则二,在不改变原本类的代码,满足我们的需求*/// 2、public static <T> void sort(T[] arr, Comparator<? super T>// 参数一:需要排序的数组// 参数二: Comoartor比较聚对象 (用来制定对象的比较规则)sort(arr1, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {// o1: 已经好序的对象 o2: 即将排序的对象// 正警数:将即将排序的对象02 放左边// 负整数:将即将排序的对象02,放右边// 0,默认按按顺序依次比较return o2.compareTo(o1);}});System.out.println(Arrays.toString(arr1));// Arrays.sort(students, new Comparator<Student>() { //匿名内部类中不能斜构造器,所有不能用comparable
// @Override
// public int compare(Student o1, Student o2) {// return Double.compare(o1.getHeight(), o2.getHeight());
// }
// });// Lambda简化/** 前提: 1、必须是接口接* 2.口中只能有一个抽、象方法* *///匿名内部类中不能斜构造器,所有不能用comparableArrays.<Student>sort(students, Comparator.comparingDouble(new ToDoubleFunction<Student>() {@Overridepublic double applyAsDouble(Student student) {double height = student.getHeight();double height1 = height;double height11 = height1;return height11;}}));System.out.println(Arrays.toString(students));}
}
Day14: 算法和数据结构
14.1 Lambda表达式
作用:用于简化匿名内部类代码的书写
14.1.1 Lambda表达式基本使用
语法格式如下:
(被重写方法的形参列表) -> {被重写方法的方法体代码;
}
注意:
在使用Lambda表达式之前,必须先有一个接口,而且接口中只能有一个抽象方法。(注意:不能是抽象类,只能是接口),且底层被"@FunctionalInterface"注解声明。
14.2 JDK8新特性(方法引用)
方法引用是用来进一步简化Lambda表达式的
14.3 常见算法
14.3.1 冒泡排序
冒泡排序核心思想:每轮对数组中元素两两之间进行比较,将较大的放右边,每轮比较结束后,都会定位出一个最大的数 (最右边),下一轮比较去描最大数,依次再比较其他的款
package com.sesameseed.d2_algorithm;import java.util.Arrays;//TODO 冒泡排序
public class Test1 {public static void main(String[] args) {// 1、准备一个数组int[] arr = {5,2,3,1};//冒泡排序核心思想:每轮对数组中元素两两之间进行比较,将较大的放右边,每轮比较结束后,都会定位出一个最大的数 (最右边),下一轮比较去描最大数,依次再比较其他的款// 2、定义一个循环控制排几轮for (int i = 0; i < args.length-1; i++) {//i=0 1 2 [5, 2, 3, 1] 次数// i = @ 第一轮 0 1 2 3// i = 1 第二轮 0 1 2// i = 2 第三轮 0 1// 3、定义一个循环控制每轮比较几次。for (int j = 0; j < arr.length - i -1; j++) {// 判断当前位置的元素值,是否大于后一个位置处的元素值,如果大则交换,if (arr[j] > arr[j + 1]){int temp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = temp;}}}System.out.println(Arrays.toString(arr));}
}
14.3.2 选择排序
核心思路是,每一轮选定一个固定的元素,和其他的每一个元素进行比较;经过几轮比较之后,每一个元素都能比较到了。
public class Test2 {public static void main(String[] args) {// 1、准备好一个数组int[] arr = {5, 1, 3, 2};// 0 1 2 3// 2、控制选择几轮for (int i = 0; i < arr.length - 1; i++) {// i = 0 第一轮 j = 1 2 3// i = 1 第二轮 j = 2 3// i = 2 第三轮 j = 3// 3、控制每轮选择几次。for (int j = i + 1; j < arr.length; j++) {// 判断当前位置是否大于后面位置处的元素值,若大于则交换。if(arr[i] > arr[j]){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}System.out.println(Arrays.toString(arr));}
}
14.3.3 查找算法
- 基本查找:只能从0索引开始一个一个往后找,但是如果元素比较多,你要查找的元素比较靠后的话,这样查找的此处就比较多。性能比较差。
- 二分查找特点,每次查找能排除一般元素,这样效率明显提高,要求元素必须有序
二分查找的核心思路
第1步:先定义两个变量,分别记录开始索引(left)和结束索引(right)
第2步:计算中间位置的索引,mid = (left+right)/2;
第3步:每次查找中间mid位置的元素,和目标元素key进行比较如果中间位置元素比目标元素小,那就说明mid前面的元素都比目标元素小此时:left = mid+1如果中间位置元素比目标元素大,那说明mid后面的元素都比目标元素大此时:right = mid-1如果中间位置元素和目标元素相等,那说明mid就是我们要找的位置此时:把mid返回
注意:一搬查找一次肯定是不够的,所以需要把第1步和第2步循环来做,只到left>end就结束,如果最后还没有找到目标元素,就返回-1.
/*** 目标:掌握二分查找算法。*/
public class Test3 {public static void main(String[] args) {// 1、准备好一个数组。int[] arr = {7, 23, 79, 81, 103, 127, 131, 147};System.out.println(binarySearch(arr, 150));System.out.println(Arrays.binarySearch(arr, 81));}public static int binarySearch(int[] arr, int data){// 1、定义两个变量,一个站在左边位置,一个站在右边位置int left = 0;int right = arr.length - 1;// 2、定义一个循环控制折半。while (left <= right){// 3、每次折半,都算出中间位置处的索引int middle = (left + right) / 2;// 4、判断当前要找的元素值,与中间位置处的元素值的大小情况。if(data < arr[middle]){// 往左边找,截止位置(右边位置) = 中间位置 - 1right = middle - 1;}else if(data > arr[middle]){// 往右边找,起始位置(左边位置) = 中间位置 + 1left = middle + 1;}else {// 中间位置处的元素值,正好等于我们要找的元素值return middle;}}return -1; // -1特殊结果,就代表没有找到数据!数组中不存在该数据!}
}
14.4 正则表达式
正则表达式其实是由一些特殊的符号组成的,它代表的是某种规则。需要用到一个方法叫`matches(String regex)
案例:正则表达式校验手机号码
/*** 目标:校验用户输入的电话、邮箱、时间是否合法。*/
public class RegexTest3 {public static void main(String[] args) {checkPhone();}public static void checkPhone(){while (true) {System.out.println("请您输入您的电话号码(手机|座机): ");Scanner sc = new Scanner(System.in);String phone = sc.nextLine();// 18676769999 010-3424242424 0104644535if(phone.matches("(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})")){System.out.println("您输入的号码格式正确~~~");break;}else {System.out.println("您输入的号码格式不正确~~~");}}}
}
Java Study Notes_Design in 2023(Day01~Day14)相关推荐
- Java Study Notes_Design in 2023(Day15~)
文章目录 Day15: 集合进阶(异常.集合) 15.1 认识异常 15.2 自定义异常 15.3 异常处理 15.4 集合概述和分类 15.4.1 集合名称图 15.4.2 集合分类(单列Colle ...
- Java实现短信验证码--(完整教程)
原 Java实现短信验证码--(完整教程) 2018年04月24日 13:03:12 北山_ 阅读数 19189更多 分类专栏: Java 阿里云 版权声明:本文为博主原创文章,遵循 CC 4.0 B ...
- Java连接数据库实现图书馆管理系统(详细教程)
该功能用到的软件为 IDEA .Navicat .云服务器(非必须) 一.建立数据库 在自己的服务器或者电脑本机安装数据库系统,本次系统演示的数据库版本为5.6. 1.创建图书管理数据库library ...
- 理解Java中的弱引用(Weak Reference)
理解Java中的弱引用(Weak Reference) 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限, ...
- 20169205实验一 Java开发环境的熟悉(Linux+IDEA)
20169205实验一 Java开发环境的熟悉(Linux+IDEA) 实验内容及步骤 使用JDK编译.运行简单的Java程序 打开windows下的cmd → 输入cd Code命令进入Code目录 ...
- 今天,Java编程周末提高班(第一期)正式结束
Java编程周末提高班(第一期),走过了近两个月历程,一共同拥有68人次学生周末到老师家进行Java学习与交流.近距离的和一群年轻的学习接触,收获非常多,特别是对以后教学的改进.在学习的闲暇.大家自己 ...
- 为什么在Java 6上Math.round(0.499999999999999917)舍入为1
总览 错误表示错误和算术舍入错误有两种类型,它们在浮点计算中很常见. 在此简单示例中,这两个错误组合在一起,在Java 6中Math.round(0.4999999999999999999917)舍入 ...
- Elasticsearch Java Low Level REST Client(通用配置)
Elasticsearch Java Low Level REST Client(通用配置) 通用配置 正如初始化中所解释的,RestClientBuilder支持提供RequestConfigCal ...
- 【零基础学Java】—finally代码块(四十七)
[零基础学Java]-finally代码块(四十七)
最新文章
- 这些片段在Android编程中很有用 (ZT)
- mysql物理优化_mysql物理优化器代价模型分析【原创】
- android代码 根据黑名单拦截短信,滴滴将小范围测试短信报警 司、乘两端同步试运行“黑名单”...
- 经典html5网页,HTML5网页设计经典
- java properties配置文件_java properties配置文件操作
- SpringSecurity 权限控制之异常处理流程图
- 搭建私有helm仓库及图形界面
- [CTF]思维导向图
- php上传png_PHP支持多种格式图片上传(支持jpg、png、gif)
- Android学习笔记(二)——TextView常用属性以及下划线、跑马灯设置
- Proxy SwitchyOmega 使用黑名单和白名单
- 程序员做饭指南,GitHub教程来了
- 计算机丢失KTcontroller,无法识别Dell Perc H310 RAID控制器上的RAID驱动器
- div+css+js实现深圳交互地图
- 我最喜欢的10个顶级数据科学资源,kaggle、TDS、arXiv......
- linux修改默认22端口失败,【原创文章】修改亚马逊AWS EC2 LINUX系统SSH默认22端口失败的原因和解决办法...
- java socket 读取文件_java中ServerSocket读取文件流不是分行读取
- svmtrain和svmpredict简介
- HDU 6194	string string string
- CVPR读书笔记[5]:Gabor特征提取之Gabor核的实现