首页 > 基础资料 博客日记
B站韩顺平学Java课程——个人笔记(1章~19章)
2024-10-11 07:00:08基础资料围观113次
Java学习笔记
Java的历史
Java诞生于1995年,创始人为大胡子gosling,后来给甲骨文公司收购。
Java的重要特点
- Java是面向对象的(oop)
- Java是健壮的,有强类型机制、异常处理、垃圾的自动收集等
- Java是跨平台的,生成的class文件可以在各个系统平台运行(基于Java虚拟机JVM)
- Java是解释性的(解释性语言编译生成的文件还需要经过一个解释器来运行,而像C/C++是编译性语言,生成的二进制文件可以直接给机器执行)
- JDK=JRE+开发工具集
- JRE=JVM+Java SE标准类库(Java核心类库)
快捷键
- ctrl+/ 集体注释
- Tab键 命令行里面填补命令
- 方向键上下键 命令行快速选择最近的命令
快速入门
~~~
命令行:
javac Hello.java //编译Hello.java文件
java Hello // 运行Hello类
方向键上下键快速选择最近的命令
Tab键填补命令
~~~
// Java代码,屏幕输出“Hello World!”
public class Hello{ // 这是一个公共类,名字叫做Hello
public static void main(String[] args){ // 这是程序的一个入口
System.out.println("Hello World!"); // 在屏幕上输出一句话
}
}
Java开发注意事项
- Java源文件以.java为扩展名,源文件的基本组成部分是类(class)。
- Java程序的应用入口是main()方法,他有固定的书写格式:
public static void main(String[] args){
}
- Java严格区分大小写。
- Java方法由一条条语句构成,每个语句以“ ; ”结束。
- 大括号都是成对出现的。
- 一个源文件中最多只有一个public类,其他类的个数不限。
- 如果源文件包含一个public类,则文件名必须和该类名一致。
- 可以把main方法写在非public类中,然后指定运行该类,这样程序的入口就是非public类的main方法。因为在编译后,一个类对应一个class文件。
学习方法
如何快速学习技术或者知识点?
- 明确需求:工作需要?入职要求?解题需要?技术控?
- 看看是否能够用传统的技术解决?能解决但是不完美,或者解决不了。
- 引出需要学习的新技术或者知识点(明确目标)。
- 学习新技术或者知识点的基本原理和基本语法(不考虑细节,掌握基础,为建知识大厦做准备)。
- 快速入门:写一个基本程序,实现基本功能如增删查改。
- 研究技术的注意事项,注意使用细节和规范,细究优化,永无止境。
转义字符
- \t:一个制表位,实现对齐的功能
- \n:换行符
- \\:一个\
- \":一个’’
- \‘:一个’
- \r:一个回车,光标返回本行首位
注释
一个良好的程序员应该有写注释的好习惯。
- 单行注释:在双斜杠后面写即可
- 多行注释:在/* */之间写即可
- 文档注释:格式如下
/**
*@author
*@version
*/
//随后使用命令行javadoc -d 文件夹名 -标签(如author) -标签 源文件名字(带后缀)
Java代码规范
- 类、方法的注释,要以javadoc的方式来写。
- 非Javadoc的注释,往往是给代码的维护者看的,着重告诉读者为什么这样写,如何修改,注重什么问题。
- 使用tab操作,实现整体往右缩进,shift+tab整体往左缩进。
- 运算符两边习惯加一个空格。
- 源文件使用utf-8编码。
- 行宽度不超过80。
- 代码编写遵循行尾风格,大括号前一个紧跟在实例后面,后一个另起一行的行头。
Dos系统
原理:接受命令->解析命令->执行命令。
相对路径:从当前目录开始寻找需要的文件的位置。
绝对路径:从根目录开始寻找需要的文件的位置。
\\ Dos系统命令
help 命令 \\ 查看命令文档
exit \\ 退出Dos系统
tree 绝对路径 \\ 查看当前路径的所有子目录
dir \\ 查看当前目录有什么内容
dir 绝对路径 \\ 查看绝对路径有什么内容
cd .. \\ 切换到上一层路径
cd /D 硬盘编号 \\ 切换当前根目录
cd 相对路径 \\ 切换到相对路径
cd 绝对路径 \\ 切换到绝对路径
第一章作业
- 配置环境变量有什么用?为了Dos系统在任何位置都可以使用Java命令。
- Java的编写步骤:第一,编写Java源代码;第二,使用Javac编译,得到后缀为.class的字节码文件;第三,使用Java运行,本质上是把字节码文件加载到JVM运行。
变量
- 变量由类型+变量名组成。
- 变量必须先声明后使用。
- 变量在同一作用域内不能重名。
程序中+号的使用
- 当左右两边都是数值型,则做加法运算。
- 当左右两边有一边是字符串,则做拼接运算。
- 运算顺序是从左到右。
数据类型
整型:
- byte(1字节)-128~127
- short(2字节)-32768~32767
- int(4字节)-2147483648~2147483647
- long(8字节) − 2 63 到 2 63 − 1 -2^{63}到2^{63-1} −263到263−1
- Java各整数类型有固定的范围和长度,不受具体OS的影响,以保证Java程序的可移植性。
- Java程序的整型具体常量默认为int型。
- long型定义的时候常量后面可以不加“l”或者“L”,但是若加了,前面的类型必须是long而不能是int。
浮点型:
- float(4字节)
- double(8字节)
- 浮点数=符号位+指数位+尾数位
- 小数都是近似值,尾数部分可能丢失,造成精度损失。
- 与整型类似,Java各浮点数类型有固定的范围和长度,不受具体OS的影响,以保证Java程序的可移植性。
- Java的浮点型常量默认为double型,声明float型常量的时候需在常量后面加“F”或者“f”。
- 浮点型常量有两种表示方式:十进制形式如5.12,5.12f,.512;科学计数法形式如5.12e2(5.12*10的2次方),5.12E-2(5.12*10的-2次方)。
- 由于机器问题,两个小数相处得出来的结果可能有误差,如8.1/3=2.699999。
字符型:
- char(2字节),存放一个字符。
- 可以放汉字
- 字符常量是用单引号’ '括起来的单个字符,绝对不能用双引号,因为那意味着这是一个字符串。
- char还可以是转义字符
- char的本质是一个整数,输出对应的unicode字符
- char类型可以进行运算
布尔型:
- boolean(1字节),存放true和false。
- java布尔类型只能存true或者false,而不像C语言可以存放其他数字。
引用数据类型:
- 类(class)
- 接口(interface)
- 数组[]
Java中文API文档
https://www.matools.com/
基本数据类型的转换
当iava程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型这个就是自动类型转换。
char->int->long->float->double
byte->short->int->long->float->double
- 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
- 当我们把精度(容量)大 的数据类型赋值给精度(容量)小 的数据类型时,就会报错,反之就会进行自动类型转换。
- byte,short,char 他们三者可以计算,在计算时首先转换为int类型。
- boolean不参与转换。
- 表达式结果的类型自动提升为 操作数中最大的类型。
- 还可以强制类型转换,但是一定要根据具体情况使用,因为可能有溢出等问题。
- 基本数据类型转string:将基本数据类型的值+""即可
- string转基本数据类型:应该基本类型的包装类调用parseXX方法即可。
运算符
注意:
- 取模实质上是:a % b = a - a / b * b
面试题
-
int i = 1; i = i++; # 问i等于多少?
代码是从右边执行到左边去的,由于++在i右边,所以对于i++的一整个整体,会先产生一个temp的变量,保存自加执行前i的值,然后进行自加的操作,使得i=2。自加完成后,此时要执行的是i = temp,故最后i是1。
-
int i = 1; i = ++i; # 问i等于多少?
代码是从右边执行到左边去的,由于++在i左边,所以对于++i的一整个整体,会先进行自加的操作,然后产生一个temp的变量,保存自加执行后i的值,即temp=i+1。自加完成后,此时要执行的是i = temp,故最后i是2。
逻辑运算符
&&(短路与)和&(逻辑与)的区别
相同点:判断结果一致
&&(短路与)和&(逻辑与):判断结果一致
有假则为假,全真则为真(有假必假,全真为真)
||(短路或)和|(逻辑或):判断结果一致
有真则为真,全假则为假(有真必真,全假为假)
不同点:判断方式不同
逻辑是从左到右全部判断
短路是能判断结果就停止,
比如:
逻辑与,2<1 & 3>1 两个都判断,false
短路与,判断2<1就已经false了,就停止判断
逻辑或,从左到右依次判断,直到结尾
短路或, 从左到右依次判断,直到出现true为止将不再判断,直接得到结果为true
赋值运算符
三元运算符
三元运算符是一个整体,精度要统一为最高精度。比如如果运算符里面有int和double,那么所有的int都会变成double。
运算符的优先级
标识符的命名规则和规范
原码、反码、补码
类与对象
IDEA快捷键
- Ctrl+Z 回退上一步的代码
- Ctrl+Y 撤销回退
- Alt+D 删除当前行
- Ctrl+D 复制当前行并粘贴到下一行
- Alt+/ 补全代码
- Ctrl+/ 添加或者撤销注释
- Alt+Enter 导入需要的包,或者生成变量名字
- Ctrl+Alt+L 快速格式化代码
- Alt+R 运行程序
- Alt+Insert 生成构造器
- Ctrl+H 查看类的层级关系
- Ctrl+B 当光标放在方法上面时,该快捷键可以定位到方法的定义
包的命名
常用的包
声明类的位置
访问修饰符
面向对象编程-封装
继承
如果子类父类有相同名字的属性怎么办
如果子类与父类的某个方法名相同,在子类中又想要调用父类的该方法,则使用【super.父类方法名】的方式来调用,如果不加super,则默认使用子类的该方法。
super关键字
方法重写
重写与重载的区别
多态
向上转型与向下转型
动态绑定机制–十分重要
在多态数组里面如何调用子类特有的方法?使用instanceof来判断是否为子类或者同类。
Object类详解
断点调试
第八章作业
Person数组排序
定义一个Person类{name, age, job},初始化Person数组,有三个person对象,并按照age从大到小进行排序,使用冒泡排序。Homework1.java
package com.albertLearnJava.homeworkEight;
public class Homework {
public static void main(String[] args) {
Person[] array = new Person[3];
array[0] = new Person("jack", 18, "student");
array[1] = new Person("marry", 20, "student");
array[2] = new Person("albert", 19, "student");
System.out.println("before sort:");
for(int i = 0;i < array.length;i++){
System.out.println(array[i].toString());
}
array[0].bubbleSort(array);
System.out.println("after sort:");
for(int i = 0;i < array.length;i++){
System.out.println(array[i].toString());
}
}
}
class Person{
private String name;
private int age;
private String job;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", job='" + job + '\'' +
'}';
}
public Person(String name, int age, String job) {
this.name = name;
this.age = age;
this.job = job;
}
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 String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public void bubbleSort(Person[] array){
Person temp = null;
int change;
for(int i = 0;i < array.length - 1;i++){
change = 0;
for(int j = 0;j < array.length - i - 1;j++){
if(array[j].getAge() < array[j + 1].getAge()){
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
change = 1;
}
}
if(change == 0){
break;
}
}
}
public String showinfo(){
return "name:" + getName() + " age:" + getAge() + " job:" + getJob();
}
}
访问修饰符权限
写出四种访问修饰符和各自的访问权限。Homework2.java
访问级别 | 访问控制修饰符 | 同类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
公开 | public | 可 | 可 | 可 | 可 |
受保护 | protected | 可 | 可 | 可 | 否 |
默认 | 没有修饰符 | 可 | 可 | 否 | 否 |
私有 | private | 可 | 否 | 否 | 否 |
编写老师类
package com.albertLearnJava.homeworkEight;
public class Homework3 {
public static void main(String[] args) {
Professor professor = new Professor("jack", 50, 5000);
associateProfessor associateprofessor = new associateProfessor("marry", 40, 2500);
lecturer lec = new lecturer("albert", 21, 10000);
System.out.println(professor.introduce() + associateprofessor.introduce() + lec.introduce());
}
}
class Teacher{
private String name;
private int age;
private String post;
private double salary;
private double grade;
public Teacher(String name, int age, String post, double salary) {
this.name = name;
this.age = age;
this.post = post;
this.salary = salary;
}
public Teacher(String name, int age) {
this.name = name;
this.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 String getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
public String introduce() {
return "name='" + name + '\'' +
", age=" + age +
", post='" + post + '\'' +
", salary=" + salary + "\n";
}
}
class Professor extends Teacher{
public Professor(String name, int age, double salary) {
super(name, age, "Professor", salary);
setGrade(1.3);
}
public String introduce(){
return "这是教授的信息>> " + super.introduce();
}
}
class associateProfessor extends Teacher{
public associateProfessor(String name, int age, double salary) {
super(name, age, "associateProfessor", salary);
setGrade(1.2);
}
public String introduce(){
return "这是副教授的信息>> " + super.introduce();
}
}
class lecturer extends Teacher{
public lecturer(String name, int age, double salary) {
super(name, age, "lecturer", salary);
setGrade(1.1);
}
public String introduce(){
return "这是讲师的信息>> " + super.introduce();
}
}
编写员工类
package com.albertLearnJava.homeworkEight;
public class Homework4 {
public static void main(String[] args) {
departmentManager albert = new departmentManager("albert", 333, 365, 1.2);
albert.setBonus(1000);
OrdinaryEmployees jack = new OrdinaryEmployees("jack", 266, 365, 1.0);
System.out.println(albert.printSalary());
System.out.println(jack.printSalary());
}
}
class staff{
private String name;
private double daySalary;
private int workDay;
private double grade;
public staff(String name, double daySalary, int workDay, double grade) {
this.name = name;
this.daySalary = daySalary;
this.workDay = workDay;
this.grade = grade;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getDaySalary() {
return daySalary;
}
public void setDaySalary(double daySalary) {
this.daySalary = daySalary;
}
public int getWorkDay() {
return workDay;
}
public void setWorkDay(int workDay) {
this.workDay = workDay;
}
public String printSalary() {
return "name:" + getName() + " salary:" + daySalary * workDay * grade;
}
}
class departmentManager extends staff{
private double bonus;
public departmentManager(String name, double daySalary, int workDay, double grade) {
super(name, daySalary, workDay, grade);
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
@Override
public String printSalary() {
return "部门经理 name:" + getName() + " salary:" + (getDaySalary() * getWorkDay() * getGrade() + bonus);
}
}
class OrdinaryEmployees extends staff{
public OrdinaryEmployees(String name, double daySalary, int workDay, double grade) {
super(name, daySalary, workDay, grade);
}
@Override
public String printSalary() {
return "普通员工 " + super.printSalary();
}
}
员工类2.0
package com.albertLearnJava.homeworkEight.h5;
public class Homework5 {
public static void main(String[] args) {
Worker wor = new Worker("大明", 5000);
Farmer fam = new Farmer("小红", 6000);
Waiter wai = new Waiter("卫国", 7000);
teacher tea = new teacher("李明", 7000, 30, 80);
Scientist sci = new Scientist("建国", 9000);
sci.setBonus(10000);
System.out.println(wor.printSalary());
System.out.println(fam.printSalary());
System.out.println(wai.printSalary());
System.out.println(tea.printSalary());
System.out.println(sci.printSalary());
}
}
class Employee{
private String name;
private double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String printSalary(){
return "姓名:" + getName() + " 工资:" + getSalary();
}
}
class Worker extends Employee{
public Worker(String name, double salary) {
super(name, salary);
}
@Override
public String printSalary() {
return "工人 " + super.printSalary();
}
}
class Farmer extends Employee{
public Farmer(String name, double salary) {
super(name, salary);
}
@Override
public String printSalary() {
return "农民 " + super.printSalary();
}
}
class Waiter extends Employee{
public Waiter(String name, double salary) {
super(name, salary);
}
@Override
public String printSalary() {
return "服务员 " + super.printSalary();
}
}
class teacher extends Employee{
private int classDay;
private double classSalary;
public teacher(String name, double salary, int classDay, double classSalary) {
super(name, salary);
this.classDay = classDay;
this.classSalary = classSalary;
}
public int getClassDay() {
return classDay;
}
public void setClassDay(int classDay) {
this.classDay = classDay;
}
public double getClassSalary() {
return classSalary;
}
public void setClassSalary(double classSalary) {
this.classSalary = classSalary;
}
@Override
public String printSalary() {
return "老师 " + "姓名:" + getName() + " 工资:" + (getSalary() + getClassDay() * getClassSalary());
}
}
class Scientist extends Employee{
private double bonus;
public Scientist(String name, double salary) {
super(name, salary);
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
@Override
public String printSalary() {
return "科学家 " + "姓名:" + getName() + " 工资:" + (getSalary() + getBonus());
}
}
银行类
package com.albertLearnJava.homeworkEight.h8;
public class BankAccount {
private double balance;
public BankAccount(double initialBalance){
this.balance = initialBalance;
}
public void deposit(double amount){
balance += amount;
}
public void withdraw(double amount){
this.balance -= amount;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
package com.albertLearnJava.homeworkEight.h8;
public class CheckingAccount extends BankAccount{
public CheckingAccount(double initialBalance) {
super(initialBalance);
}
@Override
public void deposit(double amount) {
super.deposit(amount - 1);
}
@Override
public void withdraw(double amount) {
super.withdraw(amount + 1);
}
}
package com.albertLearnJava.homeworkEight.h8;
public class newBankAccount extends CheckingAccount{
private int numPerMonth = 3;
private double rate = 1.3;
public newBankAccount(double initialBalance) {
super(initialBalance);
}
public int getNumPerMonth() {
return numPerMonth;
}
public void setNumPerMonth(int numPerMonth) {
this.numPerMonth = numPerMonth;
}
@Override
public void deposit(double amount) {
super.deposit(amount);
if(numPerMonth > 0){
setBalance(getBalance() + 1);
numPerMonth--;
}
}
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
@Override
public void withdraw(double amount) {
super.withdraw(amount);
if(numPerMonth > 0){
setBalance(getBalance() + 1);
numPerMonth--;
}
}
public void earnMonthlyInterest(){
this.numPerMonth = 3;
setBalance(getBalance() * rate);
}
}
package com.albertLearnJava.homeworkEight.h8;
public class BankMain {
public static void main(String[] args) {
newBankAccount n = new newBankAccount(3000);
System.out.println(n.getBalance());
n.deposit(20);
System.out.println(n.getBalance());
n.withdraw(20);
System.out.println(n.getBalance());
n.deposit(20);
System.out.println(n.getBalance());
n.withdraw(20);
System.out.println(n.getBalance());
n.earnMonthlyInterest();
n.deposit(20);
System.out.println(n.getBalance());
}
}
point类
package com.albertLearnJava.homeworkEight;
public class h9 {
public static void main(String[] args) {
LablePoint l = new LablePoint(20.0, 6.02, "china");
System.out.println(l.getX() + " " + l.getY() + " " + l.getLable());
}
}
class Point{
double x;
double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
}
class LablePoint extends Point{
private String lable;
public LablePoint(double x, double y, String lable) {
super(x, y);
this.lable = lable;
}
public String getLable() {
return lable;
}
public void setLable(String lable) {
this.lable = lable;
}
}
Dog类
package com.albertLearnJava.homeworkEight;
public class h10 {
public static void main(String[] args) {
Doctor d = new Doctor("jack", 15, "doctor", "man", 5000);
Doctor b = new Doctor("marry", 16, "doctor", "man", 5000);
Doctor c = new Doctor("marry", 16, "doctor", "man", 5000);
System.out.println(b.equals(d));
System.out.println(b.equals(c));
}
}
class Doctor{
private String name;
private int age;
private String job;
private String gender;
private double sal;
public Doctor(String name, int age, String job, String gender, double sal) {
this.name = name;
this.age = age;
this.job = job;
this.gender = gender;
this.sal = sal;
}
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 String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
@Override
public boolean equals(Object anotherDoctor) {
if(this == anotherDoctor){
return true;
}
if(!(anotherDoctor instanceof Doctor)){
return false;
}
return ((Doctor) anotherDoctor).getName().equals(this.getName()) && ((Doctor) anotherDoctor).getAge() == this.getAge() && ((Doctor) anotherDoctor).getGender().equals(this.getGender()) && ((Doctor) anotherDoctor).getJob().equals(this.getJob()) && ((Doctor) anotherDoctor).getSal() == this.getSal();
}
}
== 和equals的区别
房屋出租管理系统
设计
类变量和类方法
static变量在类加载的时候已经生成,存放在堆里面的共享空间,同一个类的所有对象共用一个共享空间。
main方法
代码块
先调用代码块,再运行构造器其他的内容
类加载的情况举例
单例设计模式
饿汉式:当类加载的时候就创建一个对象
懒汉式:当需要用的时候才创建一个对象
不论是饿汉式还是懒汉式,全局都只有一个对象。
final关键字
抽象类
当一个类中存在抽象方法时,需要把该类也声明为抽象类,使用abstract关键字。抽象方法没有方法体。
抽象模板设计模式
接口
在interface里面的变量都是public static final 的。
内部类
局部内部类
匿名内部类
基于哪个类或者接口创建的匿名内部类也就继承了哪个类或者实现了哪个接口。
成员内部类
静态内部类
枚举类
final和static通常搭配使用,其顺序可以调换,底层编译器做了优化处理,使用该属性时不会导致整个类的加载
增强for循环
enum常用方法
注解
Override注解
Deprecated注解
表示已经过时或者弃用了。
SuppressWarnings注解
抑制编译器警告。
元注解(了解即可)
异常处理机制
概念介绍
package Exception_;
/**
* @author Albert
* @version 1.0
*/
public class text {
public static void main(String[] args) {
try { // 算术异常
int a = 1 / 0;
} catch (Exception e) {
System.out.println(e);
}
try { // 空指针异常
String name = null;
System.out.println(name.length());
} catch (Exception e) {
System.out.println(e);
}
try { // 数组越界异常
int[] a = new int[1];
System.out.println(a[2]);
} catch (Exception e) {
System.out.println(e);
}
try { // 类型转换异常
A a = new A();
B b = (B) a;
} catch (Exception e) {
System.out.println(e);
}
try { // 数字转换异常
String num = "hhhhhh";
int n = Integer.parseInt(num);
} catch (NumberFormatException e) {
System.out.println(e);
}
}
}
class A{}
class B extends A{}
class C extends A{}
处理介绍
发生异常才会执行catch。
不管有没有异常都会执行finally,因此释放资源应该放在这里。
throws机制
try-catch机制
try { // 数字转换异常
String num = "hhhhhh";
int n = Integer.parseInt(num);
} catch (NumberFormatException e) {
System.out.println(e);
}finally {
System.out.println("hhh");
}
finally的优先度比catch里面的return还高!!
Throws机制
自定义异常
package customException;
/**
* @author Albert
* @version 1.0
*/
public class CustomException {
public static void main(String[] args) {
int age = 130;
if(!(age >= 18 && age <= 120)){
throw new AgeException("年龄需要在18~120之间");
}
}
}
class AgeException extends RuntimeException{
public AgeException(String message) {
super(message);
}
}
throw和throws的区别
异常作业
package HomeWork;
/**
* @author Albert
* @version 1.0
*/
public class H01 {
public static void main(String[] args) {
// 验证输入的两个参数是否为2个
try {
if(args.length != 2){
throw new ArrayIndexOutOfBoundsException("参数个数不对");
}
//把接收到的参数转成整数
int n1 = Integer.parseInt(args[0]);
int n2 = Integer.parseInt(args[1]);
System.out.println(cal(n1, n2));
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
} catch (NumberFormatException e){
System.out.println("参数形式不对,需要输入整数");
} catch (ArithmeticException e){
System.out.println("出现除0的情况!");
}
}
public static int cal(int a, int b){
return a / b;
}
}
先运行catch,再运行finally。
包装类(Wrapper)
public class Integer01 {
public static void main(String[] args) {
//jdk5以前是手动装箱
//手动装箱 int -> Integer
int n1 = 100;
Integer integer01 = new Integer(n1);
Integer integer02 = Integer.valueOf(n1);
//手动拆箱 Integer -> int
int i = integer01.intValue();
//jdk5以后可以自动装箱和拆箱
//自动拆箱Integer -> int
int h = 0;
h = integer01;
//自动装箱 int -> Integer
integer02 = h;
}
}
包装类型和String的相互转换
public class WrapperType01 {
public static void main(String[] args) {
//包装类(Integer)-> String
Integer i = 100;//自动装箱
//方式1
String str1 = i + "";
//方式2
String str2 = i.toString();
//方式3
String str3 = String.valueOf(i);
//String -> 包装类(Integer)
String str4 = "123456";
Integer i2 = Integer.parseInt(str4);//使用parseInt方法和自动装箱
Integer i3 = new Integer(str4);//使用构造器
}
}
Integer在加载类的时候在缓存中就已经创建好了一个Integer数组,里面存放着-128~127,可以查看源码验证。
基本数据类型int与Integer比较,比较的是基本数据类型的值是否相等,而不是判断对象是否是同一个。
String类
String的本质是char数组。
String的构造器很多,常用的只有六个,有两个用于网络编程。
String实现的Serializable接口用于网络编程,可以使String串行化(序列化);Comparable接口用于对象的比较。
方式1:查看常量池有没有“hsp”,如果有,返回“hsp”对象的地址;如果没有,在常量池中创建字符串对象“hsp”,再返回其地址。
方式2:在堆中创建一个新的空间,查看常量池有没有“hsp”,如果有,把“hsp”对象的地址赋给堆的空间,然后把堆的空间地址返回给s2;如果没有,在常量池中创建字符串对象“hsp”,把其地址赋给堆的空间,然后把堆的空间地址返回给s2。
2个
1个
public class String01 {
public static void main(String[] args) {
//创建a的时候,编译器优化,直接创建对象“ab”
String a = "a" + "b";
String b = new String("a");
//由于a和b是变量不是常量,创建c的时候,首先创建一个StringBuilder对象,
// 先使用方法append(a),再使用方法append(b)
//最后new一个以StringBuilder的值创建的String对象并返回
//可以通过在下面语句设断点,并多次跳入跳出查看
String c = a + b;
}
}
String Buffer类
package Wrapper_;
/**
* @author Albert
* @version 1.0
*/
public class StringBuffer_ {
public static void main(String[] args) {
//给价格每三位使用逗号分隔
String Price = "1234567.89";
StringBuffer sb = new StringBuffer(Price);
//先找到小数点,再循环地在该位置前三位加逗号
for(int i = sb.lastIndexOf(".") - 3;i > 0;i -= 3){
sb = sb.insert(i, ",");
}
System.out.println(Price);
System.out.println(sb);
}
}
StringBuilder类
String、StringBuffer和StringBuilder三者区别(三者具体内容面试多问,需掌握)
Math类
Arrays类
Arrays练习
package Wrapper_;
import java.util.Comparator;
/**
* @author Albert
* @version 1.0
*/
public class Arrays_ {
public static void main(String[] args) {
Book[] books = new Book[4];
books[0] = new Book("红楼梦", 100);
books[1] = new Book("金瓶梅", 90);
books[2] = new Book("青年文摘", 5);
books[3] = new Book("java从入门到放弃", 300);
java.util.Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o2.getPrice() - o1.getPrice();
}
});
for (Book book : books) {
System.out.println(book);
}
java.util.Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o1.getPrice() - o2.getPrice();
}
});
for (Book book : books) {
System.out.println(book);
}
java.util.Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o2.getName().length() - o1.getName().length();
}
});
for (Book book : books) {
System.out.println(book);
}
}
}
class Book{
private String name;
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Book(String name, int price) {
this.name = name;
this.price = price;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
System类
public class System_ {
public static void main(String[] args) {
//exit 退出当前程序
System.out.println("ok1");
//exit(0) 表示程序退出,0代表一个状态“正常”
System.exit(0);
System.out.println("ok2");
}
}
public class System_ {
public static void main(String[] args) {
//arraycopy : 复制数组元素,比较适合底层调用
//一般使用Array.copyOf完成复制数组
int[] src = {1, 2, 3};
int[] dest = new int[3]; //dest 当前是{0, 0, 0}
//五个参数
//src – the source array.
// srcPos – starting position in the source array.
// dest – the destination array.
// destPos – starting position in the destination data.
// length – the number of array elements to be copied.
System.arraycopy(src, 1, dest, 0, 2);
for(int num: dest){
System.out.println(num);
}
System.out.println(Arrays.toString(dest));
}
}
public class System_ {
public static void main(String[] args) {
//currentTimeMillens:返回当前时间距离
System.out.println(System.currentTimeMillis());
}
}
BigInteger和BigDecimal两个类
public class BigInteger_ {
public static void main(String[] args) {
BigInteger bigInteger00 = new BigInteger("2999999999999999999999999999999999999999999999");
BigInteger bigInteger01 = new BigInteger("1");
System.out.println(bigInteger00);
//在对BigInteger进行加减乘除的时候需要使用对应的方法,而不能直接使用+-*/
//可以创建一个要操作的BigInteger,然后进行操作
BigInteger addResult = bigInteger00.add(bigInteger01);
System.out.println(addResult);
BigInteger subtractResult = bigInteger00.subtract(bigInteger01);
System.out.println(subtractResult);
BigInteger multiplyResult = bigInteger00.multiply(bigInteger01);
System.out.println(multiplyResult);
BigInteger divideResult = bigInteger00.divide(bigInteger01);
System.out.println(divideResult);
}
}
public class BigDecimal_ {
public static void main(String[] args) {
BigDecimal bigDecimal01 = new BigDecimal("8569.45226466181151515162582846");
BigDecimal bigDecimal02 = new BigDecimal("2");
System.out.println(bigDecimal01);
//在对BigDecimal进行加减乘除的时候需要使用对应的方法,而不能直接使用+-*/
//可以创建一个要操作的BigDecimal,然后进行操作
System.out.println(bigDecimal01.add(bigDecimal02));
System.out.println(bigDecimal01.subtract(bigDecimal02));
System.out.println(bigDecimal01.multiply(bigDecimal02));
System.out.println(bigDecimal01.divide(bigDecimal02));//有可能碰到无限循环小数,抛出异常
System.out.println(bigDecimal01.divide(bigDecimal02, BigDecimal.ROUND_CEILING));//指定保留分子的精度就不会有异常了
}
}
日期类
第一代日期类
package Date_;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Albert
* @version 1.0
*/
public class OneDate {
public static void main(String[] args) throws ParseException {
//1.获取当前系统时间
//2.这里的Date类是在java.util包
//3.默认输出的日期是国外习惯的格式,因此通常需要对时间格式进行转换
Date d1 = new Date();//获取当前系统时间
System.out.println("Current time is " + d1);
//1.创建SimpleDateFormat对象,可以指定相应的格式
//2.这里格式使用的字母是规定好的,不能乱写
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
String format = sdf.format(d1);
System.out.println(format);
Date d2 = new Date(9234567); // 通过指定毫秒数获得时间
System.out.println(d2.getTime());// 获取某个时间对应的毫秒数
System.out.println("9234567 time is " + d2);
//1.可以把一个格式化的String转成对应的Date
//2.得到的Date输出时仍然是按照国外的形式,需要转换
//3.在把String转换为Date时,使用的sdf格式需要和给的String的格式一致,否则会抛出转换异常
String s = "2023年11月01日 05:28:28 星期三";
Date d3 = sdf.parse(s);
System.out.println(sdf.format(d3));
}
}
第二代日期类
package Date_;
import java.util.Calendar;
/**
* @author Albert
* @version 1.0
*/
public class TwoDate {
public static void main(String[] args) {
//1.Calendar是一个抽象类,并且构造器是private
//2.可以通过getInstance()来获取实例
//3.提供大量的方法和字段给程序员
//4.Calendar没有提供对应的格式化类,需要自己组合
Calendar c = Calendar.getInstance();
System.out.println(c);
//获取日历对象的某个字段
System.out.println("年: " + c.get(Calendar.YEAR));
System.out.println("月: " + (c.get(Calendar.MONTH) + 1));//加1是因为月从0开始编号
System.out.println("日: " + c.get(Calendar.DAY_OF_MONTH));
System.out.println("时: " + c.get(Calendar.HOUR));
System.out.println("时: " + c.get(Calendar.HOUR));//12小时制
System.out.println("分: " + c.get(Calendar.MINUTE));
System.out.println("秒: " + c.get(Calendar.SECOND));
}
}
第三代日期类
package Date_;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
* @author Albert
* @version 1.0
*/
public class ThreeDate {
public static void main(String[] args) {
//使用now()返回当前日期的对象,LocalDateTime有年月日时分秒
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
System.out.println("年: " + ldt.getYear());
System.out.println("月: " + ldt.getMonth());
System.out.println("月: " + ldt.getMonthValue());
System.out.println("日: " + ldt.getDayOfMonth());
System.out.println("时: " + ldt.getHour());
System.out.println("分: " + ldt.getMinute());
System.out.println("秒: " + ldt.getSecond());
//LocalDate只有年月日
LocalDate now = LocalDate.now();
//LocalTime只有时分秒
LocalTime now2 = LocalTime.now();
}
}
//使用DateTimeFormatter对象来进行格式化
LocalDateTime ldt2 = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = dateTimeFormatter.format(ldt2);
System.out.println(format);
public class instant_ {
public static void main(String[] args) {
//1.通过静态方法now()获取当前时间戳的对象
Instant now = Instant.now();
System.out.println(now);
//2.通过from可以把Instant转成Date
Date date = Date.from(now);
System.out.println(date);
//3.通过date的toInstant()可以把date转成Instant对象
Instant instant = date.toInstant();
}
}
开发中尽量使用第三代日期!!!
13章作业
作业1
package HomeWork;
/**
* @author Albert
* @version 1.0
*/
public class Homework01 {
public static void main(String[] args) {
String str = "abcdef";
String after01 = reverse01(str, 1, 2);
System.out.println(after01);
String after02 = reverse02(str, 1, 2);
System.out.println(after02);
String after03 = reverse01(str, 1, 3);
System.out.println(after03);
String after04 = reverse02(str, 1, 3);
System.out.println(after04);
}
public static String reverse01(String str, int start, int end){//自己的答案
int instance = end - start;
StringBuffer sb = new StringBuffer(str);
StringBuffer temp = new StringBuffer();
if(instance < 1){
System.out.println("Error:end比start小或者他们相等了!");
return null;
}
if((instance % 2) == 1){
int i = 0;
while(instance > 0){
temp.insert(i, sb.charAt(end - i));
temp.insert(i + 1, sb.charAt(start + i));
i++;
instance -= 2;
}
}else{
int i = 0;
while(instance > 1){
temp.insert(i, sb.charAt(end - i));
temp.insert(i + 1, sb.charAt(start + i));
i++;
instance -= 2;
}
temp.insert(i, sb.charAt(start + i));
}
sb.replace(start, end + 1, temp.toString());
return sb.toString();
}
public static String reverse02(String str, int start, int end){//韩老师的答案
if(!(str != null && start >= 0 && end > start && end < str.length())){
throw new RuntimeException("参数不在群");
}
char[] chars = str.toCharArray();
char temp = ' ';
for(int i = start, j = end;i < j;i++, j--){
temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
return new String(chars);
}
}
作业2
package HomeWork;
import java.util.Scanner;
/**
* @author Albert
* @version 1.0
*/
public class Homework02 {//我的答案
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入用户名(2~4个字符):");
StringBuffer account = new StringBuffer(scanner.next());
if(account.length() > 4 || account.length() < 2){
throw new RuntimeException("用户名字符数量不符合规定!");
}
System.out.print("请输入密码(6位纯数字):");
StringBuffer password = new StringBuffer(scanner.next());
if(password.length() != 6){
throw new RuntimeException("密码字符数量不符合规定!");
}
for(int i = 0;i < 6;i++){
if(!(password.charAt(i) == '0' || password.charAt(i) == '1' || password.charAt(i) == '2' || password.charAt(i) == '3'
|| password.charAt(i) == '4' || password.charAt(i) == '5' || password.charAt(i) == '6'
|| password.charAt(i) == '7' || password.charAt(i) == '8' || password.charAt(i) == '9')){
throw new RuntimeException("密码字符必须全部为数字!");
}
}
System.out.print("请输入邮箱:");
StringBuffer email = new StringBuffer(scanner.next());
if(email.indexOf("@") == -1 || email.indexOf(".") == -1 || email.indexOf("@") > email.indexOf(".")){
throw new RuntimeException("邮箱格式不正确!");
}
}
}
package HomeWork;
/**
* @author Albert
* @version 1.0
*/
public class Homework02_ {
public static void main(String[] args) {//老师的答案
String name = "jack";
String pwd = "123456";
String email = "jack@123.com";
try {
userRegister(name, pwd, email);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static boolean isDigital(String str){
char[] chars = str.toCharArray();
for(int i = 0;i < chars.length;i++){
if(chars[i] < '0' || chars[i] > '9'){
return false;
}
}
return true;
}
public static void userRegister(String name, String pwd, String email){
if(!(name != null && pwd != null && email != null)){
throw new RuntimeException("参数不可以为null");
}
int userLength = name.length();
if(!(userLength >= 2 && userLength <= 4)){
throw new RuntimeException("用户名长度为2~4");
}
if(!(pwd.length() == 6 && isDigital(pwd))){
throw new RuntimeException("密码的长度为6,要求全部是数字");
}
int i = email.indexOf('@');
int j = email.indexOf('.');
if(!(i > 0 && j > i)){
throw new RuntimeException("邮箱中包含 @ 和 . 并且 @ 在 . 的前面");
}
}
}
作业3
package HomeWork;
import java.util.Locale;
/**
* @author Albert
* @version 1.0
*/
public class Homework03 {//我的答案
public static void main(String[] args) {
changeFormat("hou wei dong");
}
public static void changeFormat(String name){
String[] strArray = name.split(" ");
char c = strArray[1].toUpperCase(Locale.ROOT).charAt(0);
System.out.println(strArray[2] + "," + strArray[0] + "." + c);
return ;
}
}
package HomeWork;
/**
* @author Albert
* @version 1.0
*/
public class Homework03_ {
public static void main(String[] args) {//韩老师的答案
printName("han shun ping");
}
public static void printName(String str){
if(str == null){
System.out.println("str 不可以为空");
return;
}
String[] names = str.split(" ");
if(names.length != 3){
System.out.println("str 格式不对");
return;
}
System.out.println(String.format("%s,%s .%c", names[2], names[0], names[1].toUpperCase().charAt(0)));
}
}
作业4
package HomeWork;
/**
* @author Albert
* @version 1.0
*/
public class Homework04 {
public static void main(String[] args) { // 我的答案
count("abc1235ASHD");
}
public static void count(String str){
if(str == null){
System.out.println("str 不可以为空");
return;
}
char[] chars = str.toCharArray();
int up = 0, low = 0, num = 0;
for(int i = 0;i < chars.length;i++){
if(chars[i] >= '0' && chars[i] <= '9'){
num++;
}
if(chars[i] >= 'a' && chars[i] <= 'z'){
low++;
}
if(chars[i] >= 'A' && chars[i] <= 'Z'){
up++;
}
}
System.out.println(num + "个数字," + low + "个小写字母," + up + "个大写字母");
}
}
package HomeWork;
/**
* @author Albert
* @version 1.0
*/
public class Homework04_ {
public static void main(String[] args) {//韩老师的答案
countStr("asdad56456....AADDDF");
}
public static void countStr(String str){
if(str == null){
System.out.println("输入不能为null");
return;
}
int strlen = str.length();
int lowerCount = 0;
int upperCount = 0;
int numCount = 0;
int otherCount = 0;
for(int i = 0;i < strlen;i++){
if(str.charAt(i) >= '0' && str.charAt(i) <= '9'){
numCount++;
}else if(str.charAt(i) >= 'a' && str.charAt(i) <= 'z'){
lowerCount++;
} else if (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') {
upperCount++;
}else{
otherCount++;
}
}
System.out.println("数字有:" + numCount + "个");
System.out.println("小写字母有:" + lowerCount + "个");
System.out.println("大写字母有:" + upperCount + "个");
System.out.println("其他字符有:" + otherCount + "个");
}
}
集合
集合的框架体系
单列集合,主要是一个个单个的元素
双列集合,存放的一般是键值对
collection接口和常用方法
package collectiional_;
import java.util.ArrayList;
import java.util.List;
/**
* @author Albert
* @version 1.0
*/
public class CollectionMethod {
public static void main(String[] args) {
List list = new ArrayList();
//add:添加单个元素
list.add("jack");
list.add(10);//list.add(new Integer(10))
list.add(true);
System.out.println(list);
//remove:删除指定元素
list.remove("jack");//删除指定的某个元素
System.out.println(list);
list.remove(0);//删除第一个元素
System.out.println(list);
//contains:查找元素是否存在
System.out.println(list.contains(true));
//size:获取元素的个数
System.out.println(list.size());
//isEmpty:判断集合是否为空
System.out.println(list.isEmpty());
//clear:清空集合
list.clear();
System.out.println(list);
//addAll:添加多个元素
ArrayList list2 = new ArrayList();
list2.add("红楼梦");
list2.add("三国演义");
list.addAll(list2);
System.out.println(list);
//containsAll:查找多个元素是否都存在
System.out.println(list.containsAll(list2));
//removeAll:删除多个元素
list.removeAll(list2);
System.out.println(list);
}
}
迭代器
package iterator_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
/**
* @author Albert
* @version 1.0
*/
public class iterator01 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("hhh");
c.add("aaa");
Iterator i = c.iterator();
//k快捷键,输入itit,回车快速生成迭代器遍历
while (i.hasNext()) {
Object next = i.next();
System.out.println(next);
}
i = c.iterator();//重置迭代器
while(i.hasNext()){
System.out.println(i.next());
}
}
}
增强for循环
package iterator_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
/**
* @author Albert
* @version 1.0
*/
public class iterator02 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("hhh");
c.add("aaa");
Iterator i = c.iterator();
//1.使用使用增强for,在Collection集合
//2.增强for循环底层使用的还是迭代器遍历,即是简化版的迭代器遍历
//3.快捷方式,输入I,回车
for (Object o : c) {
System.out.println(o);
}
}
}
迭代器与增强for循环练习
package iterator_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author Albert
* @version 1.0
*/
public class CollectionExercise {
public static void main(String[] args) {
Dog dog1 = new Dog("jack", 2);
Dog dog2 = new Dog("eason", 5);
Dog dog3 = new Dog("adele", 6);
Collection arrays = new ArrayList();
arrays.add(dog1);
arrays.add(dog2);
arrays.add(dog3);
Iterator iterator = arrays.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
for (Object o :arrays) {
System.out.println(o);
}
}
}
class Dog{
private String name;
private int age;
@Override
public String toString() {
return "Dog{" +
"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 Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
List接口和常用方法
package List_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Albert
* @version 1.0
*/
public class List01 {
public static void main(String[] args) {
//1.List集合元素有序,且可重复,先进先出
List arrays = new ArrayList();
arrays.add("hhh");
arrays.add("hhh");
arrays.add("aaa");
System.out.println(arrays);
//2.List支持索引,索引从0开始
System.out.println(arrays.get(2));
}
}
package List_;
import java.util.ArrayList;
import java.util.List;
/**
* @author Albert
* @version 1.0
*/
public class ListMethod {
public static void main(String[] args) {
List list = new ArrayList();
list.add("陈奕迅");
list.add("刘德华");
//void add(int index, Object ele) 在index位置插入元素ele
list.add(1, "黄伟文");
System.out.println(list);
//boolean addAll(int index, Collection eles) 从index位置开始把eles的所有元素加进来
List list2 = new ArrayList();
list2.add("王菲");
list2.add("谢安琪");
list2.add("谢安琪");
list.addAll(1, list2);
System.out.println(list);
//Object get(int index) 获取指定index位置的元素
System.out.println(list.get(2));
//int indexOf(Object obj) 返回Obj在当前集合中首次的位置
System.out.println(list.indexOf("谢安琪"));
//int lastIndexOf(Object obj) 返回Obj在当前集合中末次的位置
System.out.println(list.lastIndexOf("谢安琪"));
//移除指定index位置的元素并返回
System.out.println(list.remove(2));
System.out.println(list);
//Object set(int index, Object ele) 设置index位置的元素为ele()替换掉原来的元素
list.set(2, "谭咏麟");
System.out.println(list);
//List sublist(int fromIndex, int toIndex) 返回从fromIndex到toIndex位置的子集合
System.out.println(list.subList(2, 4));
}
}
List接口练习
package List_;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author Albert
* @version 1.0
*/
public class ListExercise {
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello0");
list.add("hello1");
list.add("hello2");
list.add("hello3");
list.add("hello4");
list.add("hello5");
list.add("hello6");
list.add("hello7");
list.add("hello8");
list.add("hello9");
list.add("hello10");
list.add(1, "韩顺平教育");
System.out.println(list.get(4));
list.remove(5);
System.out.println(list);
list.set(6, "alterHello");
System.out.println(list);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
}
}
List的三种遍历方式
package List_;
import java.util.*;
/**
* @author Albert
* @version 1.0
*/
public class ListFor {
public static void main(String[] args) {
//只要是List的实现子类都可以用下面的方法遍历
//List list = new ArrayList();
//List list = new Vector();
List list = new LinkedList();
list.add("hello0");
list.add("hello1");
list.add("hello2");
//1.迭代器遍历
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
//2.增强for循环遍历
for (Object o :list) {
System.out.println(o);
}
//3.普通for循环遍历
for(int i = 0;i < list.size();i++){
System.out.println(list.get(i));
}
}
}
List课堂练习2
package List_;
import java.util.ArrayList;
import java.util.List;
/**
* @author Albert
* @version 1.0
*/
public class ListExercise02 {
public static void main(String[] args) {
//List list = new ArrayList();
//List list = new Vector();
List list = new ArrayList();
list.add(new Book("红楼梦", "曹雪芹", 100));
list.add(new Book("西游记", "吴承恩", 10));
list.add(new Book("水浒传", "施耐庵", 9));
list.add(new Book("三国演义", "罗贯中", 80));
for(int i = 0;i < list.size() - 1;i++){
for(int j = 0;j < list.size() - i - 1;j++){
Book a = (Book)(list.get(j));
Book b = (Book)(list.get(j + 1));
if(a.getPrice() > b.getPrice()){
list.set(j, b);
list.set(j + 1 , a);
}
}
}
for (Object o :list) {
System.out.println(o);
}
}
}
class Book{
private String name;
private String author;
private double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
public Book(String name, String author, double price) {
this.name = name;
this.author = author;
this.price = price;
}
}
ArrayListDetail底层结构和源码分析
package List_;
import java.util.ArrayList;
/**
* @author Albert
* @version 1.0
*/
public class ArrayListSource {//可以设断点调试看看底层执行过程
public static void main(String[] args) {
ArrayList list = new ArrayList();
for(int i = 1;i <= 10;i++){
list.add(i);
}
list.add(11);
}
}
Vector底层结构和源码剖析
Vector与ArrayList的比较
注意:Vector可以自定义扩容增量!!!(可查看源码得到此结论)
LinkedList底层结构
LinkedList底层结构
package List_;
import java.util.Iterator;
import java.util.LinkedList;
/**
* @author Albert
* @version 1.0
*/
public class LinkedListCRUD {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList<>();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
System.out.println(linkedList);
linkedList.remove();
System.out.println(linkedList);
linkedList.set(1, 5);
System.out.println(linkedList);
linkedList.get(1);
System.out.println(linkedList);
//迭代器遍历
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
//增强for循环遍历
for (Object o :linkedList) {
System.out.println(o);
}
//普通for遍历
for(int i = 0;i < linkedList.size();i++){
System.out.println(linkedList.get(i));
}
}
}
ArrayList和LinkedList的比较
Set接口和常用方法
package Set_;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @author Albert
* @version 1.0
*/
public class setMethod {
public static void main(String[] args) {
//1.存储数据顺序与添加顺序无关
//2.不可以存放重复的数据
//3.可以存放null
//4.取出的顺序是固定的
Set set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
set.add(null);
System.out.println(set);
//使用迭代器遍历
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
set.remove(null);
//使用增强for循环遍历
for (Object o :set) {
System.out.println(o);
}
}
}
Set接口的实现类-HashSet
package Set_;
import java.util.HashSet;
/**
* @author Albert
* @version 1.0
*/
public class HashSet_ {
public static void main(String[] args) {
HashSet hashSet = new HashSet<>();
System.out.println(hashSet.add("jack"));//T
System.out.println(hashSet.add("jack"));//F
System.out.println(hashSet.add("lucy"));//T
System.out.println(hashSet.add("mary"));//T
System.out.println(hashSet);
System.out.println(hashSet.add(new Dog("rich")));//T
System.out.println(hashSet.add(new Dog("rich")));//T
//Why?
System.out.println(hashSet.add(new String("rich")));//T
System.out.println(hashSet.add(new String("rich")));//F
System.out.println(hashSet);
}
}
class Dog{
String name;
public Dog(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
}
hashcode()得到的值是hash值往右移位16位得来的。
只要总的元素size达到阈值就会触发扩容,而不是把链表里面的元素排除在外!
HashSet练习题01
package Set_;
import java.util.HashSet;
import java.util.Objects;
/**
* @author Albert
* @version 1.0
*/
public class HashSetExercise01 {
public static void main(String[] args) {
HashSet set = new HashSet<>();
System.out.println(set.add(new Employee("jack", 10)));
System.out.println(set.add(new Employee("jack", 10)));
System.out.println(set.add(new Employee("lucy", 10)));
System.out.println(set);
}
}
class Employee{
String name;
int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return age == employee.age && Objects.equals(name, employee.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
// @Override
// public int hashCode() {
// return name.hashCode() + age;
// }
// @Override
// public boolean equals(Object obj) {
// Employee other = (Employee) obj;
// return (this.name.equals(other.name) && this.age == other.age);
// }
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
HashSet练习题02
package Set_;
import java.util.HashSet;
import java.util.Objects;
/**
* @author Albert
* @version 1.0
*/
public class HashSetExercise01 {
public static void main(String[] args) {
HashSet set = new HashSet<>();
System.out.println(set.add(new Employee("jack", 10, new Birthday(2002, 8, 25))));
System.out.println(set.add(new Employee("jack", 10, new Birthday(2002, 8, 25))));
System.out.println(set.add(new Employee("lucy", 10, new Birthday(2002, 8, 25))));
System.out.println(set);
}
}
class Employee{
String name;
double sal;
Birthday birthday;
public Employee(String name, double sal, Birthday birthday) {
this.name = name;
this.sal = sal;
this.birthday = birthday;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return Objects.equals(name, employee.name) && Objects.equals(birthday, employee.birthday);
}
@Override
public int hashCode() {
return Objects.hash(name, birthday);
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", sal=" + sal +
", birthday=" + birthday +
'}';
}
}
class Birthday{
int year;
int mouth;
int day;
public Birthday(int year, int mouth, int day) {
this.year = year;
this.mouth = mouth;
this.day = day;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Birthday)) return false;
Birthday birthday = (Birthday) o;
return year == birthday.year && mouth == birthday.mouth && day == birthday.day;
}
@Override
public int hashCode() {
return Objects.hash(year, mouth, day);
}
}
Set接口实现类-LinkedHashSet
由于LinkedHashSet是继承了HashSet,所以只是在HashSet的基础上多了双向链表需要的两个节点,方便插入顺序与读取顺序一致。
package Set_;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* @author Albert
* @version 1.0
*/
public class LinkedHashSet_ {
public static void main(String[] args) {
LinkedHashSet set = new LinkedHashSet();
set.add(1);
set.add(2);
set.add(3);
}
}
LinkedHashSet练习
package Set_;
import java.util.LinkedHashSet;
import java.util.Objects;
/**
* @author Albert
* @version 1.0
*/
public class LinkedHashSetExercise01 {
public static void main(String[] args) {
LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add(new Car("HanEV", 120));
linkedHashSet.add(new Car("HanEV", 120));
linkedHashSet.add(new Car("Tang", 1320));
linkedHashSet.add(new Car("Song", 1380));
System.out.println(linkedHashSet);
}
}
class Car{
private String name;
private double price;
public Car(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Car)) return false;
Car car = (Car) o;
return Double.compare(price, car.price) == 0 && Objects.equals(name, car.name);
}
@Override
public int hashCode() {
return Objects.hash(name, price);
}
}
Map接口和常用方法
package Map_;
import java.util.HashMap;
import java.util.Map;
/**
* @author Albert
* @version 1.0
*/
public class Map_ {
public static void main(String[] args) {
Map map = new HashMap<>();
//左边是key,右边是value
map.put("nov1", "jack");
map.put("nov2", "lucy");
System.out.println(map);
//key不可以重复,重复的话新value会覆盖旧value
map = new HashMap<>();
map.put("nov1", "jack");
map.put("nov2", "lucy");
map.put("nov1", "ted");
System.out.println(map);
//value可以重复
map.put("nov3", "ted");
System.out.println(map);
//key只能有一个null,value可以多个null
map.put(null, null);
map.put(null, "abd");
map.put("aa", null);
map.put("bb", null);
System.out.println(map);
//根据key可以取出value
System.out.println(map.get(null));
System.out.println(map.get("aa"));
}
}
上面这张图直接理解为数组的多态,向上转型就OK。
package Map_;
import java.util.*;
/**
* @author Albert
* @version 1.0
*/
public class MapMethod {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("aa", "bb");
map.put("cc", "dd");
map.put("ee", "ff");
//第一组,先取出所有的key,再取出value
Set keySet = map.keySet();
//增强for
for (Object key :keySet) {
System.out.println(key + "-" + map.get(key));
}
//迭代器遍历
Iterator iterator01 = keySet.iterator();
while (iterator01.hasNext()) {
Object next = iterator01.next();
System.out.println(next + "-" + map.get(next));
}
//第二组,取出所有的value
//增强for
Collection valueSet = map.values();
for (Object value :valueSet) {
System.out.println(value);
}
//迭代器遍历
Iterator iterator02 = valueSet.iterator();
while (iterator02.hasNext()) {
Object next = iterator02.next();
System.out.println(next);
}
//第三组,使用entrySet
Set entrySet = map.entrySet();
//增强for
for (Object entry :entrySet) {
Map.Entry entry1 = (Map.Entry) entry;
System.out.println(entry1.getKey() + "-" + entry1.getValue());
}
//迭代器
Iterator iterator03 = entrySet.iterator();
while (iterator03.hasNext()) {
Object next = iterator03.next();
Map.Entry entry2 = (Map.Entry) next;
System.out.println(entry2.getKey() + "-" + entry2.getValue());
}
}
}
Map练习
package Map_;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @author Albert
* @version 1.0
*/
public class Exercise01 {
public static void main(String[] args) {
Employee e1 = new Employee("123", "jack", 2500);
Employee e2 = new Employee("124", "lucy", 35000);
Employee e3 = new Employee("125", "army", 45000);
Map map = new HashMap();
map.put(e1.getId(), e1);
map.put(e2.getId(), e2);
map.put(e3.getId(), e3);
Set keySet = map.keySet();
for (Object o :keySet) {
if(((Employee)map.get(o)).getSal() > 18000){
System.out.println((Employee)map.get(o));
}
}
Iterator iterator = keySet.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
if(((Employee)map.get(o)).getSal() > 18000){
System.out.println((Employee)map.get(o));
}
}
Set entry = map.entrySet();
Iterator iterator1 = entry.iterator();
while (iterator1.hasNext()) {
Object next = iterator1.next();
Map.Entry temp = (Map.Entry) next;
if(((Employee)temp.getValue()).getSal() > 18000){
System.out.println((Employee)temp.getValue());
}
}
}
}
class Employee{
private String id;
private String name;
public String getId() {
return id;
}
@Override
public String toString() {
return "Employee{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", sal=" + sal +
'}';
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public Employee(String id, String name, double sal) {
this.id = id;
this.name = name;
this.sal = sal;
}
private double sal;
}
Map接口的实现类-HashMap
Map接口的实现类-Hashtable
Hashtable和HashMap的区别
Map接口的实现类-Properties
开发中如何选择集合实现类
Set接口实现类-TreeSet
package Set_;
import java.util.Comparator;
import java.util.TreeSet;
/**
* @author Albert
* @version 1.0
*/
public class TreeSet_ {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet<>();
treeSet.add(1);
treeSet.add(2);
treeSet.add(3);
treeSet.add(3);//相同内容加不进去
System.out.println(treeSet);
TreeSet treeSet1 = new TreeSet(new Comparator() {//使用匿名内部类重写方法指定排序的顺序
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).compareTo(((String)o2));
}
});
treeSet1.add("jack");
treeSet1.add("tom");
treeSet1.add("amy");
treeSet1.add("check");
System.out.println(treeSet1);
}
}
Map的实现子类-TreeMap
与TreeSet的区别在于他的键值对中的value是可变的,而TreeSet的是一个Object常量。
Collections工具类
package Collections_;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @author Albert
* @version 1.0
*/
public class Collections_ {
public static void main(String[] args) {
//创建拿来测试Collections工具类的list
List list = new ArrayList<>();
list.add("jack");
list.add("tom");
list.add("rich");
list.add("mary");
//reverse:反转list中的元素
System.out.println("反转前:" + list);
Collections.reverse(list);
System.out.println("反转后:" + list);
//shuffle:随机打散list的元素
System.out.println("第一次打散前:" + list);
Collections.shuffle(list);
System.out.println("第一次打散后:" + list);
System.out.println("第二次打散前:" + list);
Collections.shuffle(list);
System.out.println("第二次打散后:" + list);
//sort:按照元素的自然顺序进行排序
System.out.println("自然排序前:" + list);
Collections.sort(list);
System.out.println("自然排序后:" + list);
//指定排序顺序(例如按照字符串的长度进行排序)
System.out.println("指定排序前:" + list);
Collections.sort(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).length() - ((String)o2).length();
}
});
System.out.println("指定排序后:" + list);
//swap(List list, int i, int j):交换list中i和j处的元素
System.out.println("交换前:" + list);
Collections.swap(list, 0, 1);
System.out.println("交换后:" + list);
//Object max(Collection):根据元素的自然排序顺序,返回给定集合中的最大值
System.out.println("自然排序中的最大值:" + Collections.max(list));
//Object max(Collection, Comparator):根据Comparator指定的排序方法,返回给定集合中的最大值(例如返回字符串最长者)
System.out.println("自然排序中的最大值:" + Collections.max(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).length() - ((String)o2).length();
}
}));
//int frequency(Collection, Object):返回给定集合中指定元素的出现次数
System.out.println("jack的出现次数是:" + Collections.frequency(list, "jack"));
//void copy(List dest, List scr):将scr中的内容复制到dest中,从dest的第一个元素开始复制过去,直到scr的内容全部复制过去为止,如果scr的长度大于dest,会报错
List list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
Collections.copy(list, list1);
System.out.println(list);
//boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换所有旧值
Collections.replaceAll(list, "rich", "Eason");
System.out.println(list);
}
}
14章集合作业
作业1
package Homework;
import java.util.ArrayList;
/**
* @author Albert
* @version 1.0
*/
public class H01 {
public static void main(String[] args) {
News news1 = new News("新冠确诊病例数超千万,数百万印度教信徒赴恒河“圣浴”引民众担忧");
News news2 = new News("男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生");
ArrayList arrayList = new ArrayList();
arrayList.add(news1);
arrayList.add(news2);
for(int i = arrayList.size() - 1;i >= 0;i--){
News tempNews = (News)arrayList.get(i);
if(tempNews.getTitle().length() > 15){
System.out.println((tempNews.getTitle().substring(0, 15) + "..."));
}else{
System.out.println(tempNews.getTitle());
}
}
}
}
class News{
private String title;
private String content;
@Override
public String toString() {
return "News{" +
"title='" + title + '\'' +
'}';
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public News(String title) {
this.title = title;
}
}
作业2
package Homework;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Objects;
/**
* @author Albert
* @version 1.0
*/
public class H02 {
public static void main(String[] args) {
ArrayList carList = new ArrayList();
//add
carList.add(new Car("比亚迪", 650000));
carList.add(new Car("蔚来", 150000));
carList.add(new Car("小鹏", 5000));
carList.add(new Car("丰田", 38000));
System.out.println(carList);
//迭代器遍历
Iterator cariterator = carList.iterator();
while (cariterator.hasNext()) {
Object next = cariterator.next();
System.out.println(next);
}
//增强for循环遍历
for (Object o :carList) {
System.out.println(o);
}
//remove
carList.remove(3);
System.out.println(carList);
carList.remove(new Car("小鹏", 5000));
System.out.println(carList);
//contains
System.out.println(carList.contains(new Car("小鹏", 5000)));
System.out.println(carList.contains(new Car("比亚迪", 650000)));
//size
System.out.println(carList.size());
//isEmpty
System.out.println(carList.isEmpty());
//clear
carList.clear();
System.out.println(carList.isEmpty());
//addAll
ArrayList carList2 = new ArrayList<>();
carList2.add(new Car("本田", 300));
carList2.add(new Car("奔驰", 500));
carList.addAll(carList2);
System.out.println(carList);
//containsAll
System.out.println(carList.containsAll(carList2));
//removeAll
carList.removeAll(carList2);
System.out.println(carList);
}
}
class Car{
private String name;
private double price;
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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Car)) return false;
Car car = (Car) o;
return Double.compare(getPrice(), car.getPrice()) == 0 && Objects.equals(getName(), car.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getPrice());
}
@Override
public String toString() {
return "Car{" + "name='" + name + '\'' + ", price=" + price + "元}";
}
public Car(String name, double price) {
this.name = name;
this.price = price;
}
}
作业3
package Homework;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @author Albert
* @version 1.0
*/
public class H03 {
public static void main(String[] args) {
Map employee = new HashMap();
employee.put("jack", 650);
employee.put("tom", 1200);
employee.put("smith", 2900);
System.out.println(employee);
employee.put("jack", 2600);
System.out.println(employee);
Iterator keyIterator = employee.keySet().iterator();
while (keyIterator.hasNext()) {
Object next = keyIterator.next();
employee.put(next, (int)employee.get(next) + 100);
}
System.out.println(employee);
keyIterator = employee.keySet().iterator();
while (keyIterator.hasNext()) {
Object next = keyIterator.next();
System.out.println(next);
}
keyIterator = employee.keySet().iterator();
while (keyIterator.hasNext()) {
Object next = keyIterator.next();
System.out.println(employee.get(next));
}
}
}
作业4
作业5
作业6
作业7
15章——泛型
引入
泛型的介绍
泛型的语法
package generic_;
import java.util.*;
/**
* @author Albert
* @version 1.0
*/
public class genericExercise {
public static void main(String[] args) {
//使用泛型放入三个学生对象到HashSet
HashSet<Student> stuSet =new HashSet<Student>();
stuSet.add(new Student("jack", 22));
stuSet.add(new Student("mary", 21));
stuSet.add(new Student("rich", 20));
for (Student stu :stuSet) {
System.out.println(stu);
}
Iterator<Student> stuIter = stuSet.iterator();
while (stuIter.hasNext()) {
Student next = (generic_.Student) stuIter.next();
System.out.println(next);
}
//使用泛型放入三个学生对象到HashMap
HashMap<String, Student> stuMap = new HashMap<String, Student>();
stuMap.put("jack", new Student("jack", 22));
stuMap.put("mary", new Student("mary", 21));
stuMap.put("rich", new Student("rich", 20));
Set<Map.Entry<String, Student>> students = stuMap.entrySet();
for (Map.Entry<String, Student> student :students) {
System.out.println(student.getKey() + " - " + student.getValue());
}
Iterator<Map.Entry<String, Student>> stud = students.iterator();
while (stud.hasNext()) {
Map.Entry<String, Student> next = stud.next();
System.out.println(next);
}
}
}
class Student{
private String name;
private int 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
泛型课堂练习
package generic_;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
/**
* @author Albert
* @version 1.0
*/
public class genericExercise02 {
public static void main(String[] args) {
ArrayList<Employee> arrayList = new ArrayList<>();
arrayList.add(new Employee("jack", 5200, new MyDate(2000, 12, 7)));
arrayList.add(new Employee("tom", 6200, new MyDate(2001, 12, 8)));
arrayList.add(new Employee("smith", 5800, new MyDate(2002, 12, 2)));
arrayList.add(new Employee("smith", 5800, new MyDate(2002, 12, 1)));
arrayList.add(new Employee("smith", 5800, new MyDate(2002, 11, 2)));
arrayList.add(new Employee("smith", 5800, new MyDate(2001, 11, 2)));
System.out.println(arrayList);
arrayList.sort(new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
int result = o1.getName().compareTo(o2.getName());
if(result == 0){
result = o1.getBirthday().compareTo(o2.getBirthday());
}
return result;
}
});
System.out.println(arrayList);
}
}
class Employee{
private String name;
private double sal;
private MyDate birthday;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return Double.compare(getSal(), employee.getSal()) == 0 && Objects.equals(getName(), employee.getName()) && Objects.equals(getBirthday(), employee.getBirthday());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getSal(), getBirthday());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", sal=" + sal +
", birthday=" + birthday +
'}';
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
public Employee(String name, double sal, MyDate birthday) {
this.name = name;
this.sal = sal;
this.birthday = birthday;
}
}
class MyDate implements Comparable<MyDate> {
private int year;
private int month;
private int day;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MyDate)) return false;
MyDate myDate = (MyDate) o;
return getYear() == myDate.getYear() && getMonth() == myDate.getMonth() && getDay() == myDate.getDay();
}
@Override
public int hashCode() {
return Objects.hash(getYear(), getMonth(), getDay());
}
public int getYear() {
return year;
}
@Override
public String toString() {
return "MyDate{" + year +
"-" + month +
"-" + day +
'}';
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
@Override
public int compareTo(MyDate otherDate) {
int result = this.getYear() - otherDate.getYear();
if(result == 0){
result = this.getMonth() - otherDate.getMonth();
}
if(result == 0){
result = this.getDay() - otherDate.getDay();
}
return result;
}
}
自定义泛型
package generic_;
/**
* @author Albert
* @version 1.0
*/
public class genericMy {
public static void main(String[] args) {
}
}
class Dog<T, S, E>{
String name;
E e;
S s;
T t;
T[] tt;
// T[] tt = new T(8); -->错误,自定义类型数组无法初始化,因为不知道开辟多大空间
// public static T tt(){}; -->错误,类加载的时候还没有定义泛型
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public E getE() {
return e;
}
public void setE(E e) {
this.e = e;
}
public S getS() {
return s;
}
public void setS(S s) {
this.s = s;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public Dog(String name, E e, S s, T t) {
this.name = name;
this.e = e;
this.s = s;
this.t = t;
}
}
package generic_;
/**
* @author Albert
* @version 1.0
*/
public class CustomInterfaceGeneric {
public static void main(String[] args) {
}
}
interface IUsb<U, R>{
//静态成员不能使用泛型
//U w;-->错误
//普通方法中可以使用接口泛型
R get(U u);
void hi(R r);
void run(R r1, R r2, U u1, U u2);
//在jdk8中可以在接口中使用默认方法可以使用泛型
default R method(U u){
return null;
}
}
interface IUsb2 extends IUsb<String, Integer>{};//继承时需要指定泛型
class A implements IUsb2{//实现类时需要对接口的有泛型的方法指定具体的泛型
@Override
public Integer get(String s) {
return null;
}
@Override
public void hi(Integer integer) {
}
@Override
public void run(Integer r1, Integer r2, String u1, String u2) {
}
}
package generic_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/7-20:03
* @describe 泛型方法的使用
*/
public class CustomMethodGeneric {
public static void main(String[] args) {
Car car = new Car();
car.run("宝马");//在调用方法时泛型被确定下来
}
}
class Car{
public <E> void run(E e){//定义在普通类中的泛型方法
System.out.println(e + " is running");
System.out.println("e 的类是:" + e.getClass());
}
}
class plane <E,T>{
public <F> void fly(F f, T t){//定义在泛型类中的泛型方法。泛型方法既可以使用类定义的泛型,也可以使用自己定义的泛型
System.out.println(f + " is flying");
}
public void stop(E e){//这个不是泛型方法,而是使用了泛型
}
}
泛型的继承和通配符
package generic_;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author Albert
* @version 1.0
* @date 2023/11/7-22:02
* @describe
*/
public class genericExtends {
public static void main(String[] args) {
//泛型没有继承性
//List<Objects> list = new ArrayList<String>();-->错误
List<Object> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<AA> list3 = new ArrayList<>();
List<BB> list4 = new ArrayList<>();
List<CC> list5 = new ArrayList<>();
//任何类型都可以
printCollection1(list1);
printCollection1(list2);
printCollection1(list3);
printCollection1(list4);
printCollection1(list5);
//只允许AA及其子类
//printCollection2(list1);-->报错
//printCollection2(list2);-->报错
printCollection2(list3);
printCollection2(list4);
printCollection2(list5);
//只允许AA及其父类
printCollection3(list1);
//printCollection3(list2);-->报错
printCollection3(list3);
//printCollection3(list4);-->报错
//printCollection3(list5);-->报错
}
//List<?> 表示任意的泛型类型都可以接受
public static void printCollection1(List<?> c){
for (Object o :c) {//
System.out.println(o);
}
}
//<? extends AA>表示上限,可以接收AA及其子类,不限于直接子类
public static void printCollection2(List<? extends AA> c){
for (Object o :c) {//
System.out.println(o);
}
}
//<? super AA>表示下限,可以接收AA及其父类,不限于直接父类
public static void printCollection3(List<? super AA> c){
for (Object o :c) {//
System.out.println(o);
}
}
}
class AA{};
class BB extends AA{};
class CC extends BB{};
JUnit介绍
import org.junit.jupiter.api.Test;
/**
* @author Albert
* @version 1.0
* @date 2023/11/8-10:12
* @describe
*/
public class JUnit_ {
public static void main(String[] args) {
}
@Test
public void m1(){//非静态方法才可以测试
System.out.println("m1 is running");
}
@Test
public void m2(){
System.out.println("m2 is running");
}
}
泛型作业
作业1
package generic_;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/**
* @author Albert
* @version 1.0
* @date 2023/11/8-9:59
* @describe
*/
public class H01 {
public static void main(String[] args) {
}
@Test
public void testList(){
DAO<User> dao = new DAO<>();
dao.save("001", new User(1, 10, "jack"));
dao.save("002", new User(2, 18, "king"));
dao.save("003", new User(3, 38, "smith"));
List<User> list = dao.list();
System.out.println(list);
System.out.println(dao.get("002"));
System.out.println(dao.delete("002"));
list = dao.list();
System.out.println(list);
dao.update("001", new User(5, 5, "mary"));
list = dao.list();
System.out.println(list);
}
}
class DAO<T>{
private HashMap<String,T> Map = new HashMap<>();
@Test
public void save(String id, T entity){
Map.put(id, entity);
}
@Test
public T get(String id){
return Map.get(id);
}
@Test
public void update(String id, T entity){
Map.put(id, entity);
}
@Test
public List<T> list(){
List<T> listt = new ArrayList<>();
Iterator iterator = Map.keySet().iterator();
while (iterator.hasNext()) {
String next = (java.lang.String) iterator.next();
listt.add(Map.get(next));
}
return listt;
}
@Test
public T delete(String id){
return Map.remove(id);
}
}
class User{
private int id;
private int age;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
public User(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
}
16章——坦克大战1.0版本
Java绘图坐标系
Java绘图技术
package draw;
import javax.swing.*;
import java.awt.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/8-20:18
* @describe
*/
public class drawCircle extends JFrame{//JFrame可以理解为一个画框
private MyPanel mp= null;
public static void main(String[] args) {
new drawCircle();
}
public drawCircle(){
//添加面板
mp = new MyPanel();
//把面板放入画框
this.add(mp);
//设置窗口的大小
this.setSize(400, 300);
//点击叉叉的时候彻底退出程序
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//使他可以显示
this.setVisible(true);
}
}
//1.先定义一个MyPanel,继承JPanel类,画图形,就在面板上
class MyPanel extends JPanel {
/*说明:
1.MyPanel 对象就是一个画板
2.Graphics g 可以把g理解成一支画笔
3.Graphics 提供了很多绘图的方法
*/
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawOval(10, 10, 100, 100);
System.out.println("正在画画~");
}
}
Graphics类及其常用方法
package draw;
import javax.swing.*;
import java.awt.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/8-20:49
* @describe
*/
public class graphics_ extends JFrame{
private MyPanel02 mp = null;
public static void main(String[] args) {
new graphics_();
}
public graphics_(){
//添加面板
mp = new MyPanel02();
//把面板放入画框
this.add(mp);
//设置窗口的大小
this.setSize(1920, 1200);
//点击叉叉的时候彻底退出程序
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//使他可以显示
this.setVisible(true);
}
}
class MyPanel02 extends JPanel {
@Override
public void paint(Graphics g) {
super.paint(g);
//画圆
//g.drawOval(10, 10, 100, 100);
System.out.println("正在画画~~");
//画直线 drawLine(int x1, int y1, int x2, int y2)
//g.drawLine(10, 10, 100, 100);
//画矩形边框 drawRect(int x, int y, int width, int height)
//g.drawRect(10, 10, 100, 100);
//填充矩形 fillRect(int x, int y, int width, int height)
//g.setColor(Color.BLUE);//设置画笔颜色
//g.fillRect(10, 10, 100, 100);
//填充椭圆 fillOval(int x, int y, int width, int height)
//g.setColor(Color.RED);
//g.fillOval(10, 10, 100, 100);
//画图片 drawImage(Image img, int x, int y, ..)
//1.获取图片资源,/bg.png 表示在该项目的根目录去获取 bg.jpg 图片资源
//Image image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bg.jpg"));
//g.drawImage(image, 0, 0, 1920, 1200, this);
//画字符串 drawString(String str, int x, int y)
//给画笔设置颜色和字体
//g.setColor(Color.red);
//g.setFont(new Font("隶书", Font.BOLD, 50));
//这里设置的100,100是“北京你好”的左下角
//g.drawString("北京你好", 100, 100);
}
}
自己画的坦克
package draw.tank;
import draw.drawCircle;
import javax.swing.*;
import java.awt.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/8-21:50
* @describe
*/
public class drawTank extends JFrame{
private MyPanel mp= null;
public static void main(String[] args) {
new drawTank();
}
public drawTank(){
//添加面板
mp = new MyPanel();
//把面板放入画框
this.add(mp);
//设置窗口的大小
this.setSize(400, 300);
//点击叉叉的时候彻底退出程序
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//使他可以显示
this.setVisible(true);
}
}
class MyPanel extends JPanel {
/*说明:
1.MyPanel 对象就是一个画板
2.Graphics g 可以把g理解成一支画笔
3.Graphics 提供了很多绘图的方法
*/
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.CYAN);
g.fillRect(90, 90, 10, 40);
g.fillRect(120, 90, 10, 40);
g.fillRect(100, 95, 20, 30);
g.drawLine(110, 70, 110, 100);
g.setColor(Color.BLUE);//设置画笔颜色
g.fillOval(100, 100, 20, 20);
System.out.println("正在画画~~");
}
}
跟着老师画的坦克
package tankgame;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-15:14
* @describe 坦克类
*/
public class Tank {
private int x;//x坐标
private int y;//y坐标
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
}
package tankgame;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-15:16
* @describe 自己的坦克
*/
public class Hero extends Tank{
public Hero(int x, int y) {
super(x, y);
}
}
package tankgame;
import javax.swing.*;
import java.awt.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-15:17
* @describe 坦克大战绘图区
*/
public class MyPanel extends JPanel {
//定义我的坦克
Hero hero = null;
public MyPanel(){
hero = new Hero(100, 100);
}
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
drawTank(hero.getX(), hero.getY(), g, 0, 0);
drawTank(hero.getX() + 60, hero.getY(), g, 0, 1);
}
/**
*
* @param x 坦克的左上角x坐标
* @param y 坦克的左上角y坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克类型(敌还是友,0是友,1是敌)
*/
public void drawTank(int x, int y, Graphics g, int direct, int type){
//根据不同的坦克设置不同的颜色
switch (type){
case 0://我们的坦克
g.setColor(Color.cyan);
break;
case 1://敌人的坦克
g.setColor(Color.yellow);
break;
}
//根据坦克的方向来画坦克
switch(direct){
case 0:
g.fill3DRect(x, y, 10, 60, false);//左边轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y);//炮筒
break;
default:
System.out.println("暂时没有处理");
}
}
}
package tankgame;
import javax.swing.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-15:24
* @describe
*/
public class TankGame01 extends JFrame {
//定义MyPanel
private MyPanel mp = null;
public static void main(String[] args) {
new TankGame01();
}
public TankGame01(){
mp = new MyPanel();
this.add(mp);
this.setSize(1000, 750);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
Java时间处理机制
package event_;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-16:15
* @describe 通过键盘上下左右移动小球演示Java的演示事件处理机制
*/
//KeyListener监听键盘事件
public class event_ extends JFrame {
MyPanel mp = null;
public static void main(String[] args) {
event_ e = new event_();
}
public event_(){
mp = new MyPanel();
this.add(mp);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 300);
this.addKeyListener(mp);//监听面板上发生的事件
this.setVisible(true);
}
}
class MyPanel extends JPanel implements KeyListener{
int x = 10;
int y = 10;
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 20, 20);
}
//有字符输出时触发
@Override
public void keyTyped(KeyEvent e) {
}
//某个键按下时触发
@Override
public void keyPressed(KeyEvent e) {
//System.out.println((char)e.getKeyCode() + "被按下");
if(e.getKeyCode() == KeyEvent.VK_DOWN){//KeyEvent.VK_DOWN代表向下的箭头
y++;
}
if(e.getKeyCode() == KeyEvent.VK_UP){//KeyEvent.VK_DOWN代表向上的箭头
y--;
}
if(e.getKeyCode() == KeyEvent.VK_LEFT){//KeyEvent.VK_DOWN代表向左的箭头
x--;
}
if(e.getKeyCode() == KeyEvent.VK_RIGHT){//KeyEvent.VK_DOWN代表向右的箭头
x++;
}
this.repaint();
}
//某个键松开时触发
@Override
public void keyReleased(KeyEvent e) {
}
}
17章——多线程
线程的相关概念
多个CPU在同时运行不同的程序,叫做并行;一个CPU在一段时间内运行不同的程序,叫做并发。
线程的基本使用
package threadUse;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-20:06
* @describe 演示通过继承Thread来创建线程
*/
public class threadUse01 {
public static void main(String[] args) throws InterruptedException {
Cat cat = new Cat();
Cat cat1 = new Cat();
cat.start();
cat.time = 5;
cat1.start();
//当main线程启动一个子进程Thread-0,主线程不会阻塞,而是继续执行
System.out.println("主线程继续执行:" + Thread.currentThread().getName());
for(int i = 0;i < 10;i++){
System.out.println("主线程 i=" + i);
//让主线程休眠
Thread.sleep(1000);
}
}
}
/*
1.当一个类继承了Thread类,该类就可以当作线程来使用
2.我们会重写run方法,写上自己的业务代码
3.run Thread类实现了Runnable接口的run方法
*/
class Cat extends Thread{
int time = 0;
@Override
public void run() {//重写run方法,写上自己的业务逻辑
while(true) {
//每隔1s在控制台输出以下内容
System.out.println("喵喵,我是小猫咪~" + (++time) + " 当前线程是:" + Thread.currentThread().getName());
//让该线程休眠1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(time == 8){//满足条件后退出while循环,随即退出线程
break;
}
}
}
}
实现Runnable接口:
package threadUse;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-20:52
* @describe 通过实现Runnable实现多线程开发
*/
public class Thread02 {
public static void main(String[] args) {
Dog dog = new Dog();
Thread thread = new Thread(dog);
thread.start();
}
}
class Dog implements Runnable{
private int count;
@Override
public void run() {
while (true) {
System.out.println("小狗汪汪叫~" + (++count) + Thread.currentThread().getName());
//休眠1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count == 10){
break;
}
}
}
}
线程练习
package threadUse;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-21:09
* @describe
*/
public class Thread03 {
public static void main(String[] args) {
Thread thread01 = new Thread(new hi());
Thread thread02 = new Thread(new helloWorld());
thread01.start();
thread02.start();
}
}
class hi implements Runnable{
int count = 0;
@Override
public void run() {
while(true){
System.out.println("hi" + (++count));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if(count == 5)break;
}
}
}
class helloWorld implements Runnable{
int count = 0;
@Override
public void run() {
while(true){
System.out.println("hello ,world" + (++count));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if(count == 10)break;
}
}
}
继承Thread与实现Runnable的区别
多线程对共享资源访问问题
package threadUse;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-21:25
* @describe 使用三个窗口模拟售票100张
*/
public class Thread04 {
public static void main(String[] args) {
// Ticket01 ticket011 = new Ticket01();
// Ticket01 ticket012 = new Ticket01();
// Ticket01 ticket013 = new Ticket01();
// ticket011.start();
// ticket012.start();
// ticket013.start();
Ticket02 ticket02 = new Ticket02();
Thread thread01 = new Thread(ticket02);
Thread thread02 = new Thread(ticket02);
Thread thread03 = new Thread(ticket02);
thread01.start();
thread02.start();
thread03.start();
}
}
class Ticket01 extends Thread{
private static int ticket = 100;
@Override
public void run() {
while (true) {
if(ticket <= 0){
System.out.println(Thread.currentThread().getName() + "售票结束!");
break;
}
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口-" + Thread.currentThread().getName() + " 售出一张票,剩余 " + (--ticket) + " 张!");
}
}
}
class Ticket02 implements Runnable{
private int ticket = 100;
@Override
public void run() {
while (true) {
if(ticket <= 0){
System.out.println(Thread.currentThread().getName() + "售票结束!");
break;
}
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口-" + Thread.currentThread().getName() + " 售出一张票,剩余 " + (--ticket) + " 张!");
}
}
}
线程终止
package exit_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-21:49
* @describe 通知线程终止
*/
public class exit_01 {
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.start();
Thread.sleep(10000);
t.setLoop(false);
}
}
class T extends Thread{
private int count = 0;
private boolean loop = true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
while (loop) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println((++count));
}
}
}
线程的常用方法
package method_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/10-10:34
* @describe
*/
public class method_ {
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.setName("李白");
t.setPriority(Thread.MIN_PRIORITY);
t.start();
//主线程打印5个hi,然后中断子线程的休眠
for(int i = 0; i < 5;i++){
Thread.sleep(1000);
System.out.println("hi" + i);
}
System.out.println(t.getName() + " 线程的优先级是:" + t.getPriority());
t.interrupt();//中断t线程的休眠
}
}
class T extends Thread{
@Override
public void run() {
while (true) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " 吃包子~~~" + i);
}
try {
System.out.println(Thread.currentThread().getName() + " 休眠中~");
Thread.sleep(10000);
} catch (InterruptedException e) {
//当线程执行到一个interrupt方法时,就会catch一个异常,可以加入自己的业务代码
System.out.println(Thread.currentThread().getName() + " 被interrupt了");
}
}
}
}
package method_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/10-11:07
* @describe
*/
public class join_ {
public static void main(String[] args) throws InterruptedException {
hi h = new hi();
h.start();
for(int i = 0; i < 20;i++){
if(i == 5){
//h.join();
Thread.yield();
System.out.println("子线程执行完毕!--------------");
}
System.out.println("hello" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
class hi extends Thread{
@Override
public void run() {
for(int i = 0; i < 20;i++){
System.out.println("hi" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
线程练习
package method_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/10-11:18
* @describe
*/
public class ThreadExercise01 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new T01());
for(int i = 1; i <= 10;i++){
System.out.println("hi" + i);
if(i == 5){
t.start();
t.join();
System.out.println("子线程执行完毕!--------------");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("主线程执行完毕!--------------");
}
}
class T01 implements Runnable{
@Override
public void run() {
for(int i = 1; i <= 10;i++){
System.out.println("hello" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
用户线程(工作线程)和守护线程
package method_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/10-11:32
* @describe
*/
public class method03 {
public static void main(String[] args) {
MyDaemonThread myDaemonThread = new MyDaemonThread();
//先设置其为主线程的守护线程,再启动线程(否则会报错)
myDaemonThread.setDaemon(true);
myDaemonThread.start();
for(int i = 0; i < 10;i++){
System.out.println("main is running~");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
class MyDaemonThread extends Thread{
@Override
public void run() {
while(true){
System.out.println("子线程正在执行~");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
线程的生命周期
package state_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/10-15:37
* @describe 演示线程的状态
*/
public class state_ {
public static void main(String[] args) throws InterruptedException {
T t = new T();
System.out.println(t.getName() + " state " + t.getState());
t.start();
while (Thread.State.TERMINATED != t.getState()) {
System.out.println(t.getName() + " state " + t.getState());
Thread.sleep(500);
}
System.out.println(t.getName() + " state " + t.getState());
}
}
class T extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("------>" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程同步机制
package synchronize_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/10-16:23
* @describe 演示synchronized关键字实现线程同步
*/
public class synchronize_ {
public static void main(String[] args) {
Ticket03 ticket03 = new Ticket03();
Thread thread01 = new Thread(ticket03);
Thread thread02 = new Thread(ticket03);
Thread thread03 = new Thread(ticket03);
thread01.start();
thread02.start();
thread03.start();
}
}
class Ticket03 implements Runnable{//使用synchronized解决线程同步问题
private int ticket = 100;
public synchronized void m(){//同步方法,保证同一时刻仅有一个线程可以使用他
while (true) {
if(ticket <= 0){
System.out.println(Thread.currentThread().getName() + "售票结束!");
break;
}
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口-" + Thread.currentThread().getName() + " 售出一张票,剩余 " + (--ticket) + " 张!");
}
}
@Override
public void run() {//
m();
}
}
互斥锁
package synchronize_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-15:07
* @describe 演示synchronized关键字实现线程同步
*/
public class synchronize_ {
public static void main(String[] args) {
Ticket03 ticket03 = new Ticket03();
Thread thread01 = new Thread(ticket03);
Thread thread02 = new Thread(ticket03);
Thread thread03 = new Thread(ticket03);
thread01.start();
thread02.start();
thread03.start();
}
}
class Ticket03 implements Runnable{//使用synchronized解决线程同步问题
private int ticket = 100;
Object obj = new Object();
//静态方法的锁是加在类上面(注意,对象是类的实例化体现)
public synchronized static void mm(){};//第一种写法
public static void mmm(){
synchronized (Ticket03.class){//第二种写法
System.out.println(1);
}
}
//非静态方法
public synchronized void sell(){//同步方法,保证同一时刻仅有一个线程可以使用他,这时所在this上
synchronized (this) {//也可以这样给代码块加synchronized关键字,这样也是锁在this上(或者把this改为 obj 也是可以的,此时锁在了obj上面)
while (true) {
if (ticket <= 0) {
System.out.println(Thread.currentThread().getName() + "售票结束!");
break;
}
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口-" + Thread.currentThread().getName() + " 售出一张票,剩余 " + (--ticket) + " 张!");
}
}
}
@Override
public void run() {//
sell();
}
}
死锁
package synchronize_;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-15:12
* @describe 模拟线程死锁
*/
public class DeadLock_ {
public static void main(String[] args) {
//模拟死锁
DeadLockDemo A = new DeadLockDemo(true);
DeadLockDemo B = new DeadLockDemo(false);
A.setName("A Thread");
B.setName("B Thread");
A.start();
B.start();
}
}
class DeadLockDemo extends Thread{
static Object o1 = new Object();//保证多线程,这里使用static
static Object o2 = new Object();
boolean flag;
public DeadLockDemo(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
/*
1.如果flag为T,线程A就会先得到/持有o1对象锁,然后尝试去获取o2对象锁
2.如果线程A得不到o2对象锁,就会Blocked
3.如果flag为F,线程B就会先得到/持有o2对象锁,然后尝试去获取o1对象锁
4.如果线程B得不到o1对象锁,就会Blocked
*/
if(flag){
synchronized (o1){//对象互斥锁
System.out.println(Thread.currentThread().getName() + "进入1");
synchronized (o2){//对象互斥锁
System.out.println(Thread.currentThread().getName() + "进入2");
}
}
}else{
synchronized (o2){//对象互斥锁
System.out.println(Thread.currentThread().getName() + "进入3");
synchronized (o1){//对象互斥锁
System.out.println(Thread.currentThread().getName() + "进入4");
}
}
}
}
}
释放锁
本章作业
作业1
package HomeWork;
import java.util.Scanner;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-15:44
* @describe A线程不断打印0~99的数字,B线程若接收到 Q ,便结束A线程跟自己。
*/
public class H01 {
public static void main(String[] args) {
A a = new A();
B b = new B(a);
b.start();
}
}
class A extends Thread{
static String loop = "A";
public static void setLoop(String loop) {
A.loop = loop;
}
@Override
public void run() {
while(!(loop.equals("Q"))){
System.out.println((int)(Math.random() * 100));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("A线程退出!");
}
}
class B extends Thread{
private A a;
public B(A a) {
this.a = a;
}
@Override
public void run() {
while(true){
String t = null;
System.out.println("请输入命令:");
Scanner scanner = new Scanner(System.in);
t = scanner.next();
if(t.equals("Q")){
A.setLoop(t);
break;
}
}
System.out.println("B线程退出");
}
}
作业2
package HomeWork;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-16:32
* @describe 作业二,两个用户从同一张卡不断取钱,每次1000,当钱不够的时候停止,卡有10000块,使用继承Thread实现
*/
public class H02 {
public static void main(String[] args) {
User jack = new User("jack");
User mary = new User("mary");
jack.start();
mary.start();
}
}
class User extends Thread {
private static int card = 10000;
private String name;
private static Object obj = new Object();//钥匙
public User(String name) {
this.name = name;
}
@Override
public void run() {
int i = 1;
while (true) {
synchronized (obj) {//判断数据和修改数据必须都在同步代码块里面,缺一不可!!!!
if (card < 1000) {
break;
}
card = card - 1000;
System.out.println(name + "取了第 " + i + " 次1000块钱," + "所剩余额为:" + card);
}
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(name + " 停止取钱!");
}
}
package HomeWork;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-17:37
* @describe 作业二,两个用户从同一张卡不断取钱,每次1000,当钱不够的时候停止,卡有10000块,使用implements接口实现
*/
public class H02_2 {
public static void main(String[] args) {
User2 user2 = new User2();
Thread A = new Thread(user2);
Thread B = new Thread(user2);
A.setName("jack");
B.setName("mary");
A.start();
B.start();
}
}
class User2 implements Runnable {
private int card = 10000;
@Override
public void run() {
int i = 1;
while (true) {
synchronized (this) {//判断数据和修改数据必须都在同步代码块里面,缺一不可!!!!
if (card < 1000) {
break;
}
card = card - 1000;
System.out.println(Thread.currentThread().getName() + "取了第 " + i + " 次1000块钱," + "所剩余额为:" + card);
}
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(Thread.currentThread().getName() + " 停止取钱!");
}
}
18章——坦克大战3.0和4.0
3.0
package tankGame3;
import javax.swing.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-18:43
* @describe
*/
public class tankGame3 extends JFrame {
//定义MyPanel
private MyPanel mp = null;
public static void main(String[] args) {
new tankGame3();
}
public tankGame3(){
mp = new MyPanel();
Thread thread = new Thread(mp);
thread.start();
this.add(mp);
this.setSize(1000, 750);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.addKeyListener(mp);
}
}
package tankGame3;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-17:00
* @describe 坦克类
*/
public class Tank {
private int x;//x坐标
private int y;//y坐标
private int direct;//坦克的方向(0:向上 1:向右 2:向下 3:向左)
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
private int speed = 1;//坦克的速度
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
//上下左右移动方法
public void moveUp(){
direct = 0;
y -= speed;
}
public void moveRight(){
direct = 1;
x += speed;
}
public void moveDown(){
direct = 2;
y += speed;
}
public void moveLeft(){
direct = 3;
x -= speed;
}
}
package tankGame3;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-18:50
* @describe 射击子弹
*/
public class Shot implements Runnable{
int x;//子弹的x坐标
int y;//子弹的y坐标
int direct;//子弹的方向
int speed = 2;//子弹的速度
public void setSpeed(int speed) {
this.speed = speed;
}
boolean isLive = true;//子弹是否存活
public Shot(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(50);//休眠50毫秒,免得看不见子弹
} catch (InterruptedException e) {
e.printStackTrace();
}
//direct 表示方向(0:向上 1:向右 2:向下 3:向左)
switch (direct) {
case 0:
y -= speed;
break;
case 1:
x += speed;
break;
case 2:
y += speed;
break;
case 3:
x -= speed;
break;
}
//测试子弹坐标
System.out.println("子弹的x坐标:" + x + " y坐标:" + y);
//当子弹移动到面板的边界时,应该销毁(把启动的子弹线程销毁)
if(!(x >= 0 && x <= 1000 && y >= 0 && y <= 750)){
isLive = false;
break;
}
}
}
}
package tankGame3;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-17:00
* @describe 坦克大战绘图区
*/
public class MyPanel extends JPanel implements KeyListener, Runnable{
//定义我的坦克
Hero hero = null;
//定义敌人的坦克,放到Vector中去,因为Vector是线程安全的
Vector<EnemyTank> enemyTanks = new Vector<>();
int enemySize = 3;//敌人坦克数量
public MyPanel() {
hero = new Hero(100, 100);
hero.setSpeed(6);
for(int i = 0; i < enemySize;i++){
enemyTanks.add(new EnemyTank(100 * (i + 1), 0));
}
}
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
//画出hero射出的子弹
if(hero.shot != null && hero.shot.isLive == true){
//g.fill3DRect(hero.shot.x, hero.shot.y, 1, 1, false);
g.drawRect(hero.shot.x, hero.shot.y, 1, 1);
}
for(int i = 0; i < enemyTanks.size();i++){
EnemyTank t = enemyTanks.get(i);
t.setDirect(2);
drawTank(t.getX(), t.getY(), g, t.getDirect(), 0);
}
//drawTank(hero.getX() + 60, hero.getY(), g, 0, 1);
}
/**
* @param x 坦克的左上角x坐标
* @param y 坦克的左上角y坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克类型(敌还是友,1是友,0是敌)
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
//根据不同的坦克设置不同的颜色
switch (type) {
case 0://敌人的坦克
g.setColor(Color.cyan);
break;
case 1://我们的坦克
g.setColor(Color.yellow);
break;
}
//根据坦克的方向来画坦克
//direct 表示方向(0:向上 1:向右 2:向下 3:向左)
switch (direct) {
case 0:
g.fill3DRect(x, y, 10, 60, false);//左边轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y);//炮筒
break;
case 1:
g.fill3DRect(x, y, 60, 10, false);//上边轮子
g.fill3DRect(x, y + 30, 60, 10, false);//下边轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//圆形盖子
g.drawLine(x + 30, y + 20, x + 60, y + 20);//炮筒
break;
case 2:
g.fill3DRect(x, y, 10, 60, false);//左边轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y + 60);//炮筒
break;
case 3:
g.fill3DRect(x, y, 60, 10, false);//上边轮子
g.fill3DRect(x, y + 30, 60, 10, false);//下边轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//圆形盖子
g.drawLine(x + 30, y + 20, x, y + 20);//炮筒
break;
default:
System.out.println("暂时没有处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//处理wasd键按下的情况
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
hero.moveUp();
}
if(e.getKeyCode() == KeyEvent.VK_D){
hero.moveRight();
}
if(e.getKeyCode() == KeyEvent.VK_S){
hero.moveDown();
}
if(e.getKeyCode() == KeyEvent.VK_A){
hero.moveLeft();
}
if(e.getKeyCode() == KeyEvent.VK_J){
hero.shotEnemyTank();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.repaint();
}
}
}
package tankGame3;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-17:00
* @describe 自己的坦克
*/
public class Hero extends Tank {
Shot shot = null;//表示一个射击行为
public Hero(int x, int y) {
super(x, y);
}
public void shotEnemyTank(){
switch (getDirect()){
case 0:
shot = new Shot(getX() + 20, getY(), 0);
break;
case 1:
shot = new Shot(getX() + 60, getY() + 20, 1);
break;
case 2:
shot = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
shot = new Shot(getX(), getY() + 20, 3);
break;
}
//启动线程
new Thread(shot).start();
}
}
package tankGame3;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-19:02
* @describe
*/
public class EnemyTank extends Tank{
public EnemyTank(int x, int y) {
super(x, y);
}
}
4.0
package tankGame4;
import javax.swing.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-18:43
* @describe
*/
public class tankGame4 extends JFrame {
//定义MyPanel
private MyPanel mp = null;
public static void main(String[] args) {
new tankGame4();
}
public tankGame4(){
mp = new MyPanel();
Thread thread = new Thread(mp);
thread.start();
this.add(mp);
this.setSize(1100, 900);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.addKeyListener(mp);
}
}
package tankGame4;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-17:00
* @describe 坦克类
*/
public class Tank {
private int x;//x坐标
private int y;//y坐标
private int direct;//坦克的方向(0:向上 1:向右 2:向下 3:向左)
boolean isLive = true;
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
private int speed = 1;//坦克的速度
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
//上下左右移动方法
public void moveUp(){
direct = 0;
y -= speed;
}
public void moveRight(){
direct = 1;
x += speed;
}
public void moveDown(){
direct = 2;
y += speed;
}
public void moveLeft(){
direct = 3;
x -= speed;
}
}
package tankGame4;
/**
* @author Albert
* @version 1.0
* @date 2023/11/13-18:50
* @describe 射击子弹
*/
public class Shot implements Runnable{
int x;//子弹的x坐标
int y;//子弹的y坐标
int direct;//子弹的方向
int speed = 8;//子弹的速度
public void setSpeed(int speed) {
this.speed = speed;
}
boolean isLive = true;//子弹是否存活
public Shot(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(50);//休眠50毫秒,免得看不见子弹
} catch (InterruptedException e) {
e.printStackTrace();
}
//direct 表示方向(0:向上 1:向右 2:向下 3:向左)
switch (direct) {
case 0:
y -= speed;
break;
case 1:
x += speed;
break;
case 2:
y += speed;
break;
case 3:
x -= speed;
break;
}
//测试子弹坐标
System.out.println("子弹的x坐标:" + x + " y坐标:" + y);
//当子弹移动到面板的边界时,应该销毁(把启动的子弹线程销毁)
if(!(x >= 0 && x <= 1000 && y >= 0 && y <= 750 && isLive)){
isLive = false;
break;
}
}
}
}
package tankGame4;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-17:00
* @describe 坦克大战绘图区
*/
public class MyPanel extends JPanel implements KeyListener, Runnable{
//定义我的坦克
Hero hero = null;
//定义敌人的坦克,放到Vector中去,因为Vector是线程安全的
Vector<EnemyTank> enemyTanks = new Vector<>();
int enemySize = 3;//敌人坦克数量
//定义一个Vector,用于存放炸弹,当子弹集中坦克时,加入一个Boom对象到booms
Vector<Bomb> bombs = new Vector<>();
//定义三张炸弹图片,用于显示爆炸效果
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel() {
hero = new Hero(500, 100);
hero.setSpeed(6);
for(int i = 0; i < enemySize;i++){
EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
enemyTanks.add(enemyTank);
//设置方向
enemyTanks.get(i).setDirect(2);
//启动线程
new Thread(enemyTank).start();
//给该敌方坦克加入一颗子弹
Shot shot = new Shot(enemyTanks.get(i).getX() + 20, enemyTanks.get(i).getY() + 60, enemyTanks.get(i).getDirect());
enemyTanks.get(i).shots.add(shot);
new Thread(shot).start();
}
//初始化图片对象
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/爆炸3.gif"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/爆炸2.gif"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/爆炸1.gif"));
}
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
//画出我方坦克
if(hero != null && hero.isLive) {
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
}
//画出hero射出的子弹
if (hero.shot != null && hero.shot.isLive) {
g.drawRect(hero.shot.x, hero.shot.y, 1, 1);
}
//画出hero射出的多颗子弹
// for(int i = 0;i < hero.shots.size();i++) {
// Shot shot = hero.shots.get(i);
// if (shot != null && shot.isLive) {
// g.drawRect(shot.x, shot.y, 1, 1);
// }else{//如果该对象已经无效,从集合中拿掉该对象
// hero.shots.remove(shot);
// }
// }
//如果booms集合中有对象,就画出
try {//加这个休眠是为了解决第一炮没有动画效果的问题,给点时间加载图片
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for(int i = 0; i < bombs.size(); i++){
//取出炸弹
Bomb bomb = bombs.get(i);
//根据当前这个Boom对象的life值去画出对应的图片
if(bomb.life > 6){
g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
}else if(bomb.life > 3){
g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
}else{
g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
}
//让生命值减少
bomb.lifeDown();
//如果bomb.life为0,就从bombs集合中删除
if(bomb.life == 0){
bombs.remove(bomb);
}
}
for(int i = 0; i < enemyTanks.size();i++){
EnemyTank t = enemyTanks.get(i);
if(t.isLive) {
drawTank(t.getX(), t.getY(), g, t.getDirect(), 0);//画敌方坦克
//画出敌方坦克的所有子弹
for (int j = 0; j < t.shots.size(); j++) {
//取出子弹
Shot shotTemp = t.shots.get(j);
//绘制
if (shotTemp.isLive) {
g.drawRect(shotTemp.x, shotTemp.y, 1, 1);
} else {
t.shots.remove(shotTemp);
}
}
}
}
}
/**
* @param x 坦克的左上角x坐标
* @param y 坦克的左上角y坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克类型(敌还是友,1是友,0是敌)
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
//根据不同的坦克设置不同的颜色
switch (type) {
case 0://敌人的坦克
g.setColor(Color.cyan);
break;
case 1://我们的坦克
g.setColor(Color.yellow);
break;
}
//根据坦克的方向来画坦克
//direct 表示方向(0:向上 1:向右 2:向下 3:向左)
switch (direct) {
case 0:
g.fill3DRect(x, y, 10, 60, false);//左边轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y);//炮筒
break;
case 1:
g.fill3DRect(x, y, 60, 10, false);//上边轮子
g.fill3DRect(x, y + 30, 60, 10, false);//下边轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//圆形盖子
g.drawLine(x + 30, y + 20, x + 60, y + 20);//炮筒
break;
case 2:
g.fill3DRect(x, y, 10, 60, false);//左边轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y + 60);//炮筒
break;
case 3:
g.fill3DRect(x, y, 60, 10, false);//上边轮子
g.fill3DRect(x, y + 30, 60, 10, false);//下边轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//圆形盖子
g.drawLine(x + 30, y + 20, x, y + 20);//炮筒
break;
default:
System.out.println("暂时没有处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//处理wasd键按下的情况
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
if(hero.getY() > 0) {
hero.moveUp();
}
}
if(e.getKeyCode() == KeyEvent.VK_D){
if(hero.getX() + 60 < 1000) {
hero.moveRight();
}
}
if(e.getKeyCode() == KeyEvent.VK_S){
if(hero.getY() + 60 < 748) {
hero.moveDown();
}
}
if(e.getKeyCode() == KeyEvent.VK_A){
if(hero.getX() > 0) {
hero.moveLeft();
}
}
if(e.getKeyCode() == KeyEvent.VK_J){//只能发射一颗子弹
if(hero.shot == null || !hero.shot.isLive) {
hero.shotEnemyTank();
}
}
//发射多颗子弹
// if(e.getKeyCode() == KeyEvent.VK_J) {//加上“ && hero.shots.size() < 5”可以控制坦克只发五颗子弹
// hero.shotEnemyTank();
// }
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//判断是否击中了敌人坦克
hitEnemyTank();
//判断多颗子弹是否打中敌方坦克
//hitEnemyTank();
//判断我方坦克是否被击中
hitHero();
this.repaint();
}
}
//判断我方坦克多颗子弹是否打中敌方坦克
// public void hitEnemyTank(){
// //遍历我方坦克子弹
// for(int j = 0; j < hero.shots.size(); j++) {
// Shot shot = hero.shots.get(j);
// //判断是否击中了敌人坦克
// if (shot != null && shot.isLive) {
// //遍历敌人所有的坦克
// for (int i = 0; i < enemyTanks.size(); i++) {
// EnemyTank enemyTank = enemyTanks.get(i);
// hitTank(hero.shot, enemyTank);
// }
// }
// }
// }
//判断我方坦克单颗子弹是否打中敌方坦克
public void hitEnemyTank(){
if (hero.shot != null && hero.shot.isLive) {
//遍历敌人所有的坦克
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
hitTank(hero.shot, enemyTank);
}
}
}
//判断敌方子弹是否打击到我方坦克
public void hitHero(){
//遍历敌人所有坦克
for(int i = 0; i < enemyTanks.size(); i++){
//取出敌人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//遍历该敌人坦克的所有子弹
for(int j = 0; j < enemyTank.shots.size(); j++){
//取出子弹
Shot shot = enemyTank.shots.get(j);
if(hero.isLive && shot.isLive){
hitTank(shot, hero);
}
}
}
}
public void hitTank(Shot shot, Tank tank){
//判断子弹s击中坦克enemyTank
switch (tank.getDirect()){
case 0:
case 2:
if(shot.x > tank.getX() && shot.x < tank.getX() + 40
&& shot.y > tank.getY() && shot.y < tank.getY() + 60){
shot.isLive = false;
tank.isLive = false;
//当我的子弹击中坦克后,将enemyTank从Vector中拿掉
enemyTanks.remove(tank);
//创建Boom对象,加入到booms集合中
Bomb bomb = new Bomb(tank.getX(), tank.getY());
bombs.add(bomb);
}
break;
case 1:
case 3:
if(shot.x > tank.getX() && shot.x < tank.getX() + 60
&& shot.y > tank.getY() && shot.y < tank.getY() + 40){
shot.isLive = false;
tank.isLive = false;
//当我的子弹击中坦克后,将enemyTank从Vector中拿掉
enemyTanks.remove(tank);
//创建Boom对象,加入到booms集合中
Bomb bomb = new Bomb(tank.getX(), tank.getY());
bombs.add(bomb);
}
break;
}
}
}
package tankGame4;
import java.util.Vector;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-17:00
* @describe 自己的坦克
*/
public class Hero extends Tank {
Shot shot = null;//表示一个射击行为
//可以发射多颗子弹
//Vector<Shot> shots = new Vector<>();
public Hero(int x, int y) {
super(x, y);
}
public void shotEnemyTank(){
// if(shots.size() == 5){//控制坦克的子弹不大于5
// return;
// }
//如果我方坦克阵亡,无法发射子弹
if(!isLive){
return;
}
switch (getDirect()){
case 0:
shot = new Shot(getX() + 20, getY(), 0);
break;
case 1:
shot = new Shot(getX() + 60, getY() + 20, 1);
break;
case 2:
shot = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
shot = new Shot(getX(), getY() + 20, 3);
break;
}
//把子弹加入到shots里面去
//shots.add(shot);
//启动线程
new Thread(shot).start();
}
}
package tankGame4;
import java.util.Random;
import java.util.Vector;
/**
* @author Albert
* @version 1.0
* @date 2023/11/9-19:02
* @describe
*/
public class EnemyTank extends Tank implements Runnable {
//在敌人坦克类,使用Vector保存多个Shot
Vector<Shot> shots = new Vector<>();
//boolean isLive = true;
public EnemyTank(int x, int y) {
super(x, y);
}
@Override
public void run() {
while (true) {
//这里我们判断如果shots.size()==0,创建一颗子弹,放入到shots集合中,并启动
if(isLive && shots.size() <= 3){
Shot s = null;
//判断坦克的方向,创建对应的子弹
switch (getDirect()){
case 0:
s = new Shot(getX() + 20, getY(), 0);
break;
case 1:
s = new Shot(getX() + 60, getY() + 20, 1);
break;
case 2:
s = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
s = new Shot(getX(), getY() + 20, 3);
break;
}
shots.add(s);
new Thread(s).start();
}
//根据坦克的方向来继续移动
switch (getDirect()) {
case 0://向上
for (int i = 0; i < 30; i++) {
if (getY() > 0) {
moveUp();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
break;
case 1://向右
for (int i = 0; i < 30; i++) {
if (getX() + 60 < 940) {
moveRight();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
break;
case 2://向下
for (int i = 0; i < 30; i++) {
if(getY() + 60 < 748) {
moveDown();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
break;
case 3://向左
for (int i = 0; i < 30; i++) {
if(getX() > 0) {
moveLeft();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
break;
}
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//然后随机改变坦克方向
setDirect((int) (Math.random() * 4));
//写并发程序,一定要考虑清楚线程的退出时机
if (!isLive) {
break;
}
}
}
}
package tankGame4;
/**
* @author Albert
* @version 1.0
* @date 2023/11/22-10:53
* @describe 炸弹效果
*/
public class Bomb {
int x , y;//炸弹的坐标
int life = 9;//炸弹的生命周期
boolean isLive = true;//是否还存活
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
//减少生命值
public void lifeDown(){//配合出现图片的爆炸效果
if(life > 0){
life--;
}else{
isLive = false;
}
}
}
19章——文件
文件的基础知识
常用的文件操作
package file_;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/22-19:46
* @describe 演示创建文件的三个方法(对应三个File的构造器)
*/
public class FileCreat {
public static void main(String[] args) {
}
//方法1
@Test
public void creat01(){
String filePath = "e:\\news1.txt";
File file = new File(filePath);
try {
file.createNewFile();
System.out.println("File is created successful!");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//方法2
@Test
public void creat02(){
String filePath = "e:\\";
File file = new File(filePath);
String fileName = "news2.txt";
//这里的file对象只是在java程序执行时创建在内存里面,只有执行了creatNewFile方法才会把该文件写进磁盘
File file1 = new File(file, fileName);
try {
file1.createNewFile();
System.out.println("File is created successful!");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//方法3
@Test
public void creat03(){
String parentPath = "e:\\";
String childPatch = "news3.txt";
//这里的file对象只是在java程序执行时创建在内存里面,只有执行了creatNewFile方法才会把该文件写进磁盘
File file = new File(parentPath, childPatch);
try {
file.createNewFile();
System.out.println("File is created successful!");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
获取文件信息
package file_;
import java.io.File;
/**
* @author Albert
* @version 1.0
* @date 2023/11/22-20:13
* @describe 演示如何获取文件信息
*/
public class FileInformation {
public static void main(String[] args) {
File file = new File("e:\\news1.txt");
//调用对应的方法得到对应的信息
System.out.println("文件的名字:" + file.getName());
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
System.out.println("文件的父级目录:" + file.getParent());
System.out.println("文件的大小(字节):" + file.length());//在UTF-8中,英文字母占1个字节,汉字占3个字节,“hello王木华”占14个字节
System.out.println("文件是否存在:" + file.exists());//T
System.out.println("是不是一个文件:" + file.isFile());//T
System.out.println("是不是一个目录:" + file.isDirectory());//F
}
}
常用的文件操作
package file_;
import org.junit.jupiter.api.Test;
import java.io.File;
/**
* @author Albert
* @version 1.0
* @date 2023/11/22-20:31
* @describe 演示常见的文件操作方法
*/
public class Directory_ {
public static void main(String[] args) {
}
//判断d:\\news1.txt是否存在,如果存在就删除(在Java中,目录被当作文件存在)
@Test
public void m1(){
String filePath = "e:\\news1.txt";
File file = new File(filePath);
if(file.exists()){
if(file.delete()){
System.out.println("Delete successful!");
}else{
System.out.println("Delete failed!");
}
}else{
System.out.println("This file is not existed!");
}
}
//mkdir()创建一级目录,mkdirs()创建多级目录
@Test
public void m2(){
String filePath = "e:\\a\\b\\c";
File file = new File(filePath);
if(file.exists()){
System.out.println("This file is already existed!");
}else{
if(file.mkdirs()){
System.out.println("make directory successful!");
}else{
System.out.println("make directory failed!");
}
}
}
}
I/O流原理及流的分类
I/O常用类——FileInputStream
package inputStream_;
import file_.FileInformation;
import org.junit.jupiter.api.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/22-21:05
* @describe 演示FileInputStream的使用
*/
public class FileInputStream_ {
public static void main(String[] args) {
}
/**
* 演示读取文件,read()单个字节地读取,效率比较低
* 为了提高效率,使用read(byte[] b)方法
*/
@Test
public void readFile01(){
String filePath = "e:\\hello.txt";
int readData = 0;
//创建FileInputStream对象,用于读取文件
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
//从该输入流读取一个字节的数据。如果没有输入可用,此方法将被阻止。如果返回-1,表示已经读取到文件末尾。
while((readData = fileInputStream.read()) != -1){
System.out.println((char)readData);
}
System.out.println("读取文件成功!");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//关闭文件输入流,节省资源
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("关闭文件输入流成功!");
}
}
/**
* 为了提高效率,使用read(byte[] b)方法
*/
@Test
public void readFile02(){
String filePath = "e:\\hello.txt";
int readLength = 0;
//字节数组
byte[] buf = new byte[8];//一次最高读取八个字节
//创建FileInputStream对象,用于读取文件
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filePath);
//从该输入流读取最多b.length字节的数据。如果没有输入可用,此方法将被阻止。如果返回-1,表示已经读取到文件末尾。如果读取正常,返回实际读取的字节数
while((readLength = fileInputStream.read(buf)) != -1){
System.out.println(new String(buf, 0, readLength));
}
System.out.println("读取文件成功!");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//关闭文件输入流,节省资源
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("关闭文件输入流成功!");
}
}
}
I/O常用类——FileOutputStream
package outputStream_;
import org.junit.jupiter.api.Test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/23-15:49
* @describe 演示使用FileOutputStream,将数据写到文件中,如果该文件不存在,则创建该文件(前提是目录存在)
*/
public class FileOutputStream01 {
public static void main(String[] args) {
}
@Test
public void writeFile() {
//创建FileOutputStream对象
String filePath = "e:\\a.txt";
FileOutputStream fileOutputStream = null;
FileOutputStream fileOutputStream2 = null;
try {
//得到FileOutputStream对象
fileOutputStream = new FileOutputStream(filePath);//这种创建方式会覆盖文件的旧数据
fileOutputStream2 = new FileOutputStream(filePath, true);//这种创建方式会在文件的末尾追加新数据,不会覆盖掉旧数据
//写入一个字节
fileOutputStream.write('H');
//写入一个字符数组(字符串自带方法转换)
fileOutputStream.write("hello,world".getBytes());
//写入指定字符串数组指定位置的字符(实例意思是从0号位置开始读取三个字节写入,本例即写入“cat”)
fileOutputStream.write("cat eat fish".getBytes(), 0, 3);
fileOutputStream2.write("cat eat fish".getBytes(), 4, 3);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
package outputStream_;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/23-16:28
* @describe 使用FileInputStream与FileOutputStream配合来完成文件拷贝
*/
public class FileCopy {
public static void main(String[] args) {
//完成文件拷贝
/**
* 1.创建文件输入流,把文件读入内存
* 2.创建文件输出流,把读取到内存的文件数据写入到指定位置
*/
String srcFilePath = "E:\\下载\\BingWallpaper.jpg";
String destFilePath = "E:\\BingWallpaper.jpg";
FileInputStream fileInputStream= null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcFilePath);
fileOutputStream = new FileOutputStream(destFilePath);
//定义一个字节数组,提高读取效果
byte[] buf = new byte[1024];
int readLen = 0;
while((readLen = fileInputStream.read(buf)) != -1){
//读到后立刻写进去
fileOutputStream.write(buf, 0, readLen);//一定要使用这个方法写!!
}
System.out.println("Copy successful!");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(fileInputStream != null) {
fileInputStream.close();
}
if(fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
文件拷贝
package outputStream_;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/23-16:28
* @describe 使用FileInputStream与FileOutputStream配合来完成文件拷贝
*/
public class FileCopy {
public static void main(String[] args) {
//完成文件拷贝
/**
* 1.创建文件输入流,把文件读入内存
* 2.创建文件输出流,把读取到内存的文件数据写入到指定位置
*/
String srcFilePath = "E:\\下载\\BingWallpaper.jpg";
String destFilePath = "E:\\BingWallpaper.jpg";
FileInputStream fileInputStream= null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcFilePath);
fileOutputStream = new FileOutputStream(destFilePath);
//定义一个字节数组,提高读取效果
byte[] buf = new byte[1024];
int readLen = 0;
while((readLen = fileInputStream.read(buf)) != -1){
//读到后立刻写进去
fileOutputStream.write(buf, 0, readLen);//一定要使用这个方法写!!
}
System.out.println("Copy successful!");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(fileInputStream != null) {
fileInputStream.close();
}
if(fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
文件字符流说明
I/O常用类——FileReader
package Reader_;
import org.junit.jupiter.api.Test;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/23-17:06
* @describe 演示FileReader的使用
*/
public class FileReader01 {
public static void main(String[] args) {
}
//使用read()依次读取单个字符
@Test
public void readFile01(){
String filePath = "e:\\story.txt";
FileReader fileReader = null;
int data = 0;
//创建FileReader对象
try {
fileReader = new FileReader(filePath);
//循环读取,使用read() # 返回的是UTF-8的字符码
while((data = fileReader.read()) != -1){
System.out.print((char)data);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
//使用read(char[] buf),每次读取buf.length个字符,放入buf中
@Test
public void readFile02() {
String filePath = "e:\\story.txt";
FileReader fileReader = null;
int readLen = 0;
char[] buf = new char[100];
//创建FileReader对象
try {
fileReader = new FileReader(filePath);
//循环读取,使用read(buf) # 返回的是读取到的字符数,如果是-1,表示读取到文件的末尾了
while ((readLen = fileReader.read(buf)) != -1) {
System.out.print(new String(buf, 0, readLen));
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if (fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
I/O常用类——FileWriter
package Writer_;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/23-17:33
* @describe 演示FileWriter的使用
*/
public class FileWriter01 {
public static void main(String[] args) {
String filePath = "e:\\note.txt";
//创建FileWriter对象
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(filePath);//这是覆盖模式
//fileWriter = new FileWriter(filePath, true);//这是覆盖模式
//1.每次写入一个字符
fileWriter.write('H');
//2.写入指定数组
char[] buf = {'a', 'b', 'c'};
fileWriter.write(buf);
//3.写入字符数组指定部分
fileWriter.write("hello,world".toCharArray(), 0, 5);
//4.写入整个字符串
fileWriter.write("ABC");
//5.写入字符串指定部分
fileWriter.write("DF", 0, 2);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if(fileWriter != null){
//对于FileWriter,一定要关闭流,或者flush才能真正把数据写入到文件
try {
//fileWriter.flush();
//fileWriter.close()等价于fileWriter.flush() + 一个关闭动作
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
System.out.println("The program is done!");
}
}
节点流和处理流
BufferReader
package Reader_;
import java.io.FileReader;
/**
* @author Albert
* @version 1.0
* @date 2023/11/24-9:54
* @describe 演示BufferReader的使用
*/
public class BufferedReader {
public static void main(String[] args) throws Exception{
String filePath = "e:\\hello.txt";
//创建BufferReader
java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new FileReader(filePath));
//读取
String line = null;//按行读取,效率高
//1.bufferedReader.readLine()是按行读取文件
//2.当返回null时,读取完毕
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
//关闭流,只需要关闭bufferedReader就可以了,因为底层会去关闭节点流FileReader
bufferedReader.close();
}
}
BufferedWriter
package Writer_;
import java.io.BufferedWriter;
import java.io.FileWriter;
/**
* @author Albert
* @version 1.0
* @date 2023/11/24-10:14
* @describe 演示BufferedWriter的使用
*/
public class BufferedWriter_ {
public static void main(String[] args) throws Exception{
String filePath = "e:\\ok.txt";
//创建BufferedWriter
//BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));以覆盖方式写入
//BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));以追加方式写入
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
bufferedWriter.write("hello,world!");
bufferedWriter.write("hello,world!");
bufferedWriter.newLine();//换行
bufferedWriter.write("hello,world!");
bufferedWriter.write("hello,world!\n");//或者使用 \n 换行
bufferedWriter.write("hello,world!\n");
//关闭处理流
bufferedWriter.close();
}
}
使用BufferedReader与BufferedWriter拷贝文件
package Writer_;
import java.io.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/24-10:36
* @describe 使用BufferedReader与BufferedWriter拷贝文件
* 注意不要用上述两个类操作二进制文件如图片、视频、音频、doc、pdf等,有概率造成文件损坏!
*/
public class BufferedCopy_ {
public static void main(String[] args) {
String srcFilePath = "e:\\ok.txt";
String destFilePath = "e:\\hello1.txt";
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
String line = null;
try {
bufferedReader = new BufferedReader(new FileReader(srcFilePath));
bufferedWriter = new BufferedWriter(new FileWriter(destFilePath));
while((line = bufferedReader.readLine()) != null){
bufferedWriter.write(line + "\n");
System.out.println(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(bufferedWriter != null) {
bufferedWriter.close();
}
if(bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
Buffered字节处理流
package outputStream_;
import java.io.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-10:21
* @describe 演示BufferedInputStream和BufferedOutputStream的使用,可以完成拷贝二进制文件的操作
*/
public class BufferCopy02 {
public static void main(String[] args) {
String srcFilePath = "e:\\BingWallpaper.jpg";
String destFilePath = "e:\\Wallpaper.jpg";
byte[] buf = new byte[1024];
int readLen = 0;
//创建BufferedInputStream和BufferedOutputStream的对象
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(srcFilePath));
bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
while((readLen = bis.read(buf)) != -1){
bos.write(buf, 0, readLen);
}
System.out.println("Copy successful!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bis != null) {
bis.close();
}
if(bos != null) {
bos.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("Shut down BufferedInputStream and BufferedOutputStream successful!");
}
}
}
对象处理流(序列化与反序列化)
package outputStream_;
import java.io.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-11:13
* @describe 演示ObjectOutputStream的使用,完成数据的序列化
*/
public class ObjectOutputStream01 {
public static void main(String[] args) throws Exception {
//序列化后,保存的文件后缀可以自定义,保存时是按照他自有的格式保存的,如果你自定义为txt,在外面双击时不一定打得开
String filePath = "e:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到"e:\\data.dat"
oos.writeInt(100);//装包int -> Integer(实现了Serializable)
oos.writeBoolean(true);//装包boolean -> Boolean(实现了Serializable)
oos.writeChar('a');//装包char -> Character(实现了Serializable)
oos.writeDouble(100.0);//装包double -> Double(实现了Serializable)
oos.writeUTF("你好");//String(实现了Serializable)
//序列化对象
oos.writeObject(new Dog("jack", 10));
System.out.println("序列化成功");
}
}
//一定要实现Serializable接口才可以进行序列化与反序列化
class Dog implements Serializable{
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
package inputStream_;
import outputStream_.Dog;
import java.io.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-11:40
* @describe
*/
public class ObjectInputStream01 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//指定反序列化的对象
String filePath = "e:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
//反序列化时一定要按照序列化的顺序进行读取
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
Object dog = ois.readObject();
System.out.println(dog);
//关闭
ois.close();
//如果希望对Dog对象进行操作,使用它的方法,需要将Dog对象的定义引用过来(使那个类成为公有的允许导入包),才可以正常使用
Dog dog2 = (Dog) dog;//向下转型
System.out.println(dog2.getAge());
System.out.println(dog2.getName());
}
}
package outputStream_;
import java.io.Serializable;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-12:02
* @describe
*/
//一定要实现Serializable接口才可以进行序列化与反序列化
public class Dog implements Serializable {
private String name;
private int 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;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
标准输入输出流
转换流InputStreamReader和OutputStreamWriter
学IO最重要的是学会在什么时候使用什么流!
上图第三个构造器可以传入一个字节输入流,并制定一个编码方式,用来转换成字符输入流。下图同理。
注意:保存TXT文件时如果选择编码“ANSI”,指代的是当前操作系统的国家编码。当前自己的操作系统是中文,那么它指代的编码为“GBK”。
package transformation_;
import java.io.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-16:01
* @describe 演示使用InputStreamReader解决中文乱码问题。将FileInputStream字节流转换为字符输入流InputStreamReader,指定编码UTF-8
*/
public class InputStreamReader_ {
public static void main(String[] args) throws IOException {
String filePath = "e:\\story.txt";
//使用InputStreamReader将字节输入流按照“gbk”编码并包装成字符输入流
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "gbk"));
String s = br.readLine();
System.out.println("读取第一行的内容为:" + s);
//关闭外层流
br.close();
}
}
package transformation_;
import java.io.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-16:23
* @describe 演示OutputStreamWriter的使用。把字节流FileOutputStream转成字符流OutputStreamWriter,编码可以为 gbk/utf-8/utf8
*/
public class OutputStreamWriter_ {
public static void main(String[] args) throws IOException {
String filePath = "e:\\LiBai.txt";
String charSet = "utf-8";
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
osw.write("君不见黄河之水天上来,奔流到海不复还");
osw.close();
System.out.println("按照" + charSet + "编码保存文件成功!");
}
}
打印流PrintStream和PrintWriter
package printStream_;
import java.io.IOException;
import java.io.PrintStream;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-16:36
* @describe 演示字节打印流
*/
public class PrintStream_ {
public static void main(String[] args) throws IOException {
PrintStream out = System.out;
out.print("李白爱写诗");
//print底层用的还是write,使用也可以这样写
out.write("李白爱写诗".getBytes());
out.close();
//我们还可以去修改打印流输出的位置/设备
//1.输出修改到“e:\\f1.txt”
//2."杜甫也爱写诗"将输出到“e:\\f1.txt”
System.setOut(new PrintStream("e:\\f1.txt"));
System.out.println("杜甫也爱写诗");
}
}
package printStream_;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-16:56
* @describe 演示PrintWriter的使用方法
*/
public class PrintWriter_ {
public static void main(String[] args) throws IOException {
//输出到屏幕上
PrintWriter printWriter = new PrintWriter(System.out);
printWriter.println("SpaceX发射火箭失败!");
printWriter.close();
//输出到屏幕上
PrintWriter printWriter2 = new PrintWriter(new FileWriter("e:\\f2.txt"));
printWriter2.println("SpaceX发射火箭失败!");
printWriter2.close();//flush + 关闭流,才会把数据写入到文件中
}
}
Properties类
package Properties_;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-17:19
* @describe 使用Properties类来读取配置文件
*/
public class Properties02 {
public static void main(String[] args) throws IOException {
//1.创建Properties对象
Properties properties = new Properties();
//2.加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
//3.把k-v显示到控制台
properties.list(System.out);
//4.根据key获取value
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println("用户名=" + user);
System.out.println("密码=" + pwd);
}
}
package Properties_;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-17:31
* @describe 使用Properties类来创建或者修改配置文件
*/
public class Properties03 {
public static void main(String[] args) throws IOException {
//创建
Properties properties = new Properties();
//如果key值已经存在,那么会更新该key值的value,否则会添加该k-v
properties.setProperty("charset", "utf-8");
properties.setProperty("user", "李白");
properties.setProperty("pwd", "666666");
//将k-v存储到文件中
properties.store(new FileOutputStream("src\\mysql2.properties"), null);//null 这个地方的参数是注释,字符串类型
System.out.println("保存配置文件成功!");
}
}
19章作业
package HomeWork;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-17:49
* @describe 1、在判断e盘下是否有文件夹 mytemp,如果没有就创建 mytemp
* 2、在 e\\:mytemp 目录下,创建文件 hello.txt
* 3、如果 hello.txt 已经存在,提示该文件已经存在,就不要再重复创建了
* 4、如果 hello.txt 已经存在,在 hello.txt 写入 “hello,world!”
*/
public class H01 {
public static void main(String[] args) throws IOException {
String fileName1 = "e:\\mytemp";
String fileName2 = "e:\\mytemp\\hello.txt";
File file1 = new File(fileName1);
File file2 = new File(fileName2);
if (!(file1.exists())) {
if(file1.mkdir()){
System.out.println("文件夹创建成功!");
}else{
System.out.println("文件夹创建失败!");
}
}
if (!(file2.exists())) {//也可以使用file2.creatNewFile()来创建文件
FileOutputStream fileOutputStream = new FileOutputStream(file2);
fileOutputStream.write("hello,world!".getBytes());
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
fileOutputStream.close();
}
}
}
}
package HomeWork;
import org.junit.jupiter.api.Test;
import java.io.*;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-20:23
* @describe 要求: 使用BufferedReader读取一个文本文件,为每行加上行号,再连同内容一并输出到屏幕上。
*/
public class H02 {
public static void main(String[] args) throws IOException {
String filePath = "e:\\story.txt";
int i = 0;
String line = null;
BufferedReader bufferedReader = null;
bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "gbk"));//指定编码
while((line = bufferedReader.readLine()) != null){
i++;
System.out.println("第 " + i + " 行 " + line);
}
if(bufferedReader != null){
bufferedReader.close();
}
}
}
package HomeWork;
import java.io.*;
import java.util.Properties;
/**
* @author Albert
* @version 1.0
* @date 2023/11/25-20:40
* @describe (1) 要编写一个 dog.properties name=tom age=5 color=red
* (2) 编写Dog 类(name,age,color) 创建一个dog对象,读取dog.properties 用相应的内容完成属性初始化,并输出
* (3) 将创建的Dog 对象 ,序列化到 文件 dog.dat 文件
*/
public class H03 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Properties dogInf = new Properties();
dogInf.load(new FileReader("src\\dog.properties"));
Dog dog = new Dog(dogInf.getProperty("name"), Integer.parseInt(dogInf.getProperty("age")), dogInf.getProperty("color"));
System.out.println(dog);
//序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\\dog.dat"));
oos.writeObject(dog);
oos.close();
//反序列化
System.out.println("反序列化:");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\dog.dat"));
Object o = ois.readObject();
ois.close();
dog = (Dog) o;
System.out.println(dog);
}
}
class Dog implements Serializable{
private String name;
private int age;
private String color;
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
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 String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Dog(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
上一篇:Java-数据类型与变量
下一篇:【Java 优选算法】双指针(下)