JAVA企业级开发学习笔记

杂项

image-20220925154621932

image-20220925154703398

image-20220925154854585

image-20221225123323121

image-20221225123746302

快捷键 I

image-20230112150931969

image-20230118155734188

image-20230123153131164

image-20230123154248645

while + iterator的快捷键itit,ctrl + j调出快捷键列表 ,遍历完一次后想重置iterator iterator = 名字.iterator

JAVA概述

JAVA API 在线文档 www.matools.com

JAVA发展历史

1990 sun公司启动绿色计划,1992年创建java语言,1994gosling参加硅谷大会演示java功能震惊世界,1995年sun公司发布java第一个版本,2009年甲骨文公司宣布收购sun公司。2014发布java8,广泛应用的版本。

JAVA技术平台

JAVA SE:JAVA标准版,支持面向桌面级应用的平台,提供了完整的JAVA核心API,此版本之前称为J2SE

JAVA EE:JAVA企业版,为开发企业环境下的应用程序提供一套解决方案。主要针对Web应用程序开发,此版本之前称为J2EE

JAVA ME:JAVA小型版,支持java程序运行在移动终端上的平台,对java api有所精简,加入了针对移动终端的支持,此版本之前称为J2ME

JAVA重要特点

  1. Java语言是面向对象的(oop)
  2. Java语言是健壮的。Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮
    性的重要保证
  3. Java语言是跨平台性的。[即:一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台]
  4. Java语言是解释型的
    解释性语言:javascript,PHP., java 编译性语言:c/ c++
    区别是:解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行,编译性语言,编译后的代码,可以直接被机器执行

JAVA运行机制

image-20220919152040950

跨平台的核心:JVM(JAVA虚拟机)

image-20220919152533862

JDK与JRE,JVM

image-20220919152958633

image-20220919153034480

关于环境变量的配置

image-20220919154310799

JAVA开发注意事项

image-20220919163750057

JAVA转义字符

image-20220919172342729

这里需要注意的是换行和回车的区别,换行是将光标移动到下一行,而回车是将光标移动到当前行的开始第一个字符

JAVA易犯错误(新手时期)

image-20220919172758704

JAVA注释类型

单行注释://

多行注释:/*

​ …

*/

多行注释内部不允许嵌套多行注释

文档注释:注释内容可以被JDK提供的工具javadoc解析,生成一套以网页文件形式体现的该程序的说明文档,一般写在类

基本格式:/**

​ *

​ *

​ */

如何生成对应的文档注释:javadoc -d 文件夹 -xx -yy 需要生成的java文件名字

其中xx和yy是javadoc标签

JAVA代码规范

image-20220922020457579

常用DOS命令

image-20220922021807695

JAVA基本程序设计结构

数据类型

image-20220922200348524

image-20220922201940070

基本数据类型

整数

image-20220922202333875

image-20220922210900451

浮点数

image-20220922211142974

image-20220922213501148

image-20220922213241955

字符类型

image-20220923195114071

image-20220923195031450

image-20220923200316874

布尔类型

image-20220924191931772

与C或C++不同,不可以用0或非0的数代替false或者true;

引用数据类型

数组

image-20220927151259386

image-20220927151727987

image-20220927152939283

image-20220927153129494

image-20220927153439060

数组拷贝
  • 浅拷贝

image-20220928183603422

  • 深拷贝

    image-20220928183952186

二维数组

数组的每个元素是一个数组

image-20220928200415098

image-20220929112538132

动态初始化,列数不确定,每个一维数组的长度不一样

image-20220929113157020

image-20220929114920895

数组练习

image-20220929115709975

数据类型转换

自动转换

image-20220924193324992

image-20220924220414625

image-20220924220737834

强制转换

image-20220924222637581

image-20220924222659237

基本数据类型与string类型的转换

image-20220924222606181

image-20220924223056140

运算符与标识符

image-20220925132050581

算术运算符

image-20220925132130638

image-20220925133520600

关于%取模运算符,它的运算公式为 a % b = a − ( i n t ) a / b ∗ b a \%b = a - (int)a / b * b a%b=a(int)a/bb,经过证明,取模的结果的符号与 a a a的符号相同。

++的魔鬼细节

image-20220925140615232

“+” 的使用(连接符)

image-20220922201337521

关系运算符

image-20220925142635072

逻辑运算符

image-20220925143540203

image-20220925143606554

image-20220925143813520

对于短路与 & & \&\& &&而言,如果第一个为假,后面的条件不会执行也不会判断,逻辑与 & \& &则都要判断执行;

同样的对于短路或 ∣ ∣ || ∣∣,如果第一个为真,后面的条件不会执行和判断,逻辑 ∣ | 则都要判断执行;

赋值运算符

image-20220925151526294

image-20220925151733173

三元运算符

image-20220925152107815

image-20220925152304379

位运算符

image-20220925160404295

image-20220925161151271

运算符优先级

image-20220925152931014

标识符

image-20220925153217629

image-20220925153610775

控制结构

顺序控制

image-20220926165207248

分支结构

image-20220926165500828

image-20220926165923353

image-20220926170744224

image-20220926171507454

image-20220926172105095

switch细节

image-20220926172259863

image-20220926173028849

循环结构
for

image-20220926174012227

image-20220926174723989

while

image-20220926175511843

do while

image-20220926175957788

多重循环

image-20220927133158104

跳转控制
break

image-20220927140701926

image-20220927140749677

image-20220927141110987

continue

image-20220927141920035

return

image-20220927143047966

排序

image-20220928192958090

image-20220928193035446

查找

image-20220928195716735

对象与类

对象与类介绍

image-20220929161237789

image-20220929161415693

image-20220930144820605

image-20220930150617556

image-20220930150856082

类的内存分配

image-20220930150425198

image-20220930151132384

image-20220930152420110

成员方法

image-20220930171934313

image-20220930173234144

image-20220930181205451

image-20220930181816577

image-20220930182514481

image-20221001175630366

image-20221001180029577

image-20221001181928837

image-20221001182726996

对象克隆

image-20221001184227186

递归

image-20221001191827089

经典问题掌握猴子吃桃,斐波那契数列,汉诺塔问题,八皇后问题,走迷宫问题。

重载

image-20221012160612537

image-20221012161120765

image-20221012162000033

可变参数的形参访问与数组类似,通过形参名[下标]访问.

image-20221012162244631

作用域

image-20221012163717931

image-20221012164021545

image-20221012164347702

构造方法/构造器

image-20221012164709604

image-20221012164727017

image-20221012164850740

image-20221012165133161

image-20221012165640220

image-20221012170051579

image-20221012170227671

this

image-20221012170533505

会发现打印的name和age仍然是默认值

image-20221012171009978

image-20221012171228501

image-20221012171809211

哪个对象调用,this就指向哪个对象

image-20221013114843400

image-20221013111625120

访问修饰符

image-20221213101909369

image-20221213102053399

封装

image-20221213104411911

image-20221213104707936

image-20221213104904100

继承

image-20221214162011203

image-20221214162604388

image-20221214162530733

image-20221214165638015

image-20221214171516801

image-20221214172410028

image-20221214172923241

image-20221214173237068

继承的本质

image-20221214220045058

image-20221214220146329

super

image-20221215165006733

image-20221215170352875

image-20221215171311254

image-20221215171507355

方法重写/覆盖

image-20221215172243920

image-20221215173123836

image-20221215173316258

多态

image-20221216110747616

image-20221216111235030

image-20221216113056681

image-20221216130639457

image-20221217144454461

image-20221217144400406

image-20221217150127675

image-20221217150536686

image-20221217150922644

image-20221217152947934

image-20221218123420079

Object类详解

image-20221218124140420

image-20221218125439843

image-20221219103905079

image-20221219111141690

image-20221219115548825

类变量(静态变量)

会被该类的所有实例对象所共享

image-20221225110841687

image-20221225111352012

image-20221225111746103

类方法

image-20221225112854023

image-20221225121332267

image-20221225121748173

代码块

image-20221225124041649

image-20221225124518518

image-20221225124443434

image-20221225125404466

image-20221225125925155

当涉及到继承的时候

image-20221225130543918

image-20221225131435713

final

image-20221225134754969

image-20221225135235781

image-20221225135512635

抽象类

image-20221226150501595

image-20221226150817640

image-20221226150844514

image-20221226151417546

image-20221226151546733

接口

image-20230110161542995

image-20230110161731984

image-20230110163908227

可以对代码进行规范的管理调用

image-20230110164315662

image-20230110164835931

image-20230110165904598

一方面相对于C++的多继承机制,或许JAVA中的接口实现是对单继承的补充

image-20230110170141176

image-20230110170916336

image-20230110171128066

内部类

image-20230111143516128

image-20230111143654385

局部内部类

image-20230111144854667

image-20230111145624971

匿名内部类

image-20230111153308473

image-20230111154728230

image-20230111155034121

image-20230111155215357

image-20230111155447929

image-20230111155959278

成员内部类

image-20230111161342204

image-20230111161946123

image-20230111162034876

静态内部类

image-20230111162251400

image-20230111162640440

image-20230111162548847

image-20230111162924817

枚举类

image-20230112142935491

image-20230112143034492

自定义枚举类型

image-20230112144015306

image-20230112144055483

enum关键字实现枚举

image-20230112145049276

image-20230112150105657

image-20230112151418881

image-20230112151903315

注解Annotation

image-20230112152110767

Override

image-20230112152305250

image-20230112152505347

Override作语法校验

image-20230112152725933

image-20230112152843045

Deprecated

image-20230112153000318

image-20230112153308364

SuppressWarnings

image-20230112153617317

image-20230112153845973

image-20230112153906486

元注解

image-20230112154136659

Retention

image-20230112155046503

image-20230112155150824

Target

image-20230112155333425

Documented

image-20230112155606024

Inherited

image-20230112155747333

异常

概念

image-20230116150336722

体系图 (很重要)

image-20230116150812332

image-20230116151302723

常见运行时异常

image-20230116151537030

image-20230116151559750

image-20230116151623316

image-20230116151758886

image-20230116151949920

常见编译异常

image-20230116152206750

异常处理

image-20230116152527423

image-20230116152849811

image-20230116160056634

try-catch-finally

image-20230116154102495

image-20230116154414470

image-20230116154801503

image-20230116154857417

image-20230116155437943

image-20230116155604458

throws处理机制

image-20230116160429966

image-20230116160357704

image-20230116160938706

image-20230116161211735

自定义异常

image-20230116161524770

image-20230116161939152

image-20230117171757941

常用类

包装类

image-20230118154403467

image-20230118154346732

image-20230118154331641

image-20230118154320309

image-20230118155539273

image-20230118160131011

image-20230118160340893

image-20230118160746957

image-20230118161317498

String

image-20230118162241385

image-20230118161650867

image-20230118162137132

image-20230118162538581

image-20230118162512413

image-20230118163054411

image-20230118163713860

image-20230118163959288

image-20230119132250334

image-20230119133302567

image-20230119134749268

image-20230119134947586

image-20230119141851187

StringBuffer

image-20230119142938365

image-20230119142953827

image-20230119143127800

image-20230119143504578

image-20230119143534541

image-20230119144113660

image-20230119144940829

image-20230119145256874

StringBuilder

image-20230119145824283

image-20230119150109397

image-20230119150047899

image-20230119150251925

image-20230119172829524

image-20230122151213539

Math

image-20230119173641100

Arrays

image-20230122134915268

image-20230122134929983

System

image-20230122140308376

BigInteger和BigDecimal

image-20230122142140788

image-20230122142205186

Date,Calendar,第三代日期类

image-20230122142605461

image-20230122142823576

image-20230122143123204

image-20230122143751933

image-20230122143712249

image-20230122143604195

image-20230122143959040

image-20230122144329212

image-20230122144733437

image-20230122145149472

集合

image-20230123151604936

单列集合,存放单值

image-20230123151858804

双列集合,存放键值对

image-20230123151959803

Collection

image-20230123152356115

image-20230123152831879

image-20230123155234995

image-20230123155214476

List

image-20230123160121042

image-20230123160419471

ArrayList

image-20230123162638943

image-20230123163009226

无参构造的源码

image-20230123164911111

image-20230123164941196

有参构造的源码

image-20230123165048364

Vector

image-20230123165352235

image-20230123165443955

LinkedList

image-20230123170121084

image-20230123170255252

自己dubug下CRUD的源码

image-20230123171926163

Set

image-20230124145702105

image-20230124150209509

image-20230124150019965

HashSet

image-20230124150511147

image-20230124174311432

image-20230124175046177

hashset加入节点时,只要增加一个元素不管是在数组上还是挂载在链表上,size都要自增

LinkedHashSet

image-20230307171114467

image-20230307171408399

Map

image-20230312115139081

image-20230312122051966

image-20230312122311939

image-20230312122743473

image-20230312123721530

image-20230312125223247

image-20230312125527186

image-20230312125910993

Hashtable

image-20230312145859676

扩容机制是乘以2倍再加1

Propertise

image-20230312150627238# 工具类

Collections

image-20230312154019247

image-20230312154046823

image-20230312154414522

泛型

image-20230312202050079

image-20230312202445176

image-20230312203710030

image-20230312204019677

image-20230312205209240

image-20230312205321555

image-20230313101207820

image-20230313102125632

image-20230313102830005

image-20230313103237540

image-20230313104151782

JAVA绘图

image-20230313111139111

image-20230313111205505

image-20230313112402090

image-20230313112536007

image-20230313112557669

image-20230313125915623

image-20230313130006611

image-20230313135219465

image-20230313135700375

image-20230313135629249

多线程

image-20230313154727827

image-20230313154836598

image-20230313155218584

image-20230313155519695

image-20230313180934094

image-20230313181135435

image-20230313182902278

image-20230313182944655

image-20230313183801396

image-20230313201334319

image-20230313201311489

image-20230313201449299

interru一般用于中断线程休眠

image-20230313201544991

image-20230313201642325

image-20230313202550587

image-20230313204030846

image-20230313203948474

image-20230313213019459

image-20230313213826834

image-20230313214015131

image-20230313214937002

image-20230313215215784

image-20230314090619969

image-20230314090845701

image-20230314091809215

image-20230314092026135

IO流

image-20230314171747738

image-20230314171921421

image-20230315002404721

image-20230315002933336

mkdirs创建多级目录

image-20230315003346846

image-20230315003419909

image-20230315004044423

image-20230315004058889

InputStream

image-20230315004302771

OutputStream

image-20230315005723963

image-20230315010220358

image-20230315011029008

FileReader && FileWriter

image-20230315011248169

image-20230315021054989

image-20230315022350125

包装流、处理流

image-20230315023337889

image-20230315023228237

image-20230315023025652

image-20230315024402781

image-20230315024939886

image-20230315025808213

image-20230315030007743

image-20230315031114909

image-20230315031856399

image-20230315032226355

image-20230315032936755

image-20230315033335299

image-20230315033416647

image-20230315103311231

image-20230315104311284

image-20230315110249990

image-20230315111408581

image-20230315111526535

image-20230315111746564

image-20230315112027335

网络编程

image-20230315114637422

image-20230315115359770

image-20230315115418193

image-20230315120253493

image-20230315120754042

image-20230315140930861

image-20230315145117896

image-20230316135105711

image-20230316135332765

image-20230316140157648

image-20230316140753938

发送方通常要设置一个结束标记,socket.shutdownOutput().

image-20230316144425742

image-20230316144743929

image-20230316150828407

netstat -anb 可以查看端口被哪个程序占用,cmd需要管理员权限

image-20230316152003945

image-20230316152613624

反射

image-20230316154505876

image-20230316154417871

image-20230316155137462

image-20230316173430436

image-20230316155727830

image-20230316155916037

image-20230316160359458

image-20230316161031944

image-20230316161016191

image-20230316170908542

image-20230316172624996

image-20230316173357463

image-20230316173525908

image-20230316173513597

image-20230316173604915

image-20230316173637615

image-20230316173719781

int.class和Integer.TYPE是同一个对象

image-20230316174957822

image-20230316200155355

image-20230316200410037

image-20230316200602338

image-20230316200723425

image-20230316200918921

image-20230316201203895

image-20230316201151268

image-20230316201407340

image-20230316202910759

image-20230316203302176

image-20230316203541427

image-20230316203605661

image-20230316205129215

image-20230316205236879

image-20230316205643320

IDEA开发

常用快捷键

  • 删除当前行 CTRL + D;
  • 复制当前行 ctrl + alt +向下箭头
  • 补全代码 alt + /
  • 取消注释和添加注释 ctrl + /
  • 自动导包 alt + enter
  • 格式化代码 ctrl + alt + L
  • 生成构造器 alt + insert
  • 查看类的层级关系 ctrl + h
  • 方法定位 ctrl + b
  • 自动分配变量名,在后面加.var
  • ctrl+alt+t 好东西

image-20221212112820828

image-20221212122017411

image-20221213101706555

将set方法写入构造器可以控制外部通过构造器对属性的修改。

断点调试

image-20221219120024431

数据库与MySql

image-20230317014911633

image-20230317022058130

image-20230317022158429

image-20230317022501851

image-20230317023625441

image-20230317023909117

image-20230317023931857

image-20230317102553269

image-20230317103015225

image-20230317103825238

image-20230317103807978

image-20230317104301016

image-20230317104531326

image-20230317105041550

image-20230317105438496

image-20230317105814490

Sqlyog注释的快捷键,shift + ctrl +c,取消为 shift + ctrl + r

image-20230317110332697

image-20230317110604502

image-20230317110700965

image-20230317110831050

image-20230317111158808

image-20230317111624147

image-20230317112031628

image-20230317112113879

image-20230317112229820

image-20230317113013166

image-20230317113230627

image-20230317113406634

image-20230317113517251

image-20230317113712190

单表查询

image-20230317114633689

image-20230317114913399

image-20230317115159107

image-20230317115428064

image-20230317115732690

image-20230317120110494

image-20230317120814807

image-20230317120931097

image-20230317121106841

image-20230317121321482

image-20230317123527812

image-20230317123717818

image-20230320145110304

image-20230320145314996

image-20230320145330129

image-20230320145932992

image-20230320150446169

image-20230320150423773

image-20230320151018800

image-20230320152055708

image-20230320153212540

image-20230320153231743

image-20230320154304643

多表查询

image-20230320154954151

image-20230320161727974

自连接

image-20230320162316317

把一个查询结果当做另一个查询的条件

image-20230320162735372

把子查询当做临时表解决查询问题

image-20230320163345919

image-20230320163553727

image-20230320163606226

多列子查询

image-20230320163949417

自我复制

image-20230320165025434

如何对一张表去重

image-20230320165320552

查询合并

image-20230320165800417

外连接

image-20230320170616446

MySql约束

image-20230320170944351

image-20230320171108126

DESC 表名 查看表的结构

image-20230320171950241

image-20230320171725335

image-20230320172135732

image-20230320172928744

image-20230320173113782

image-20230320173240942

image-20230320174132701

image-20230320174351868

索引

image-20230321142312389

image-20230321142657044

image-20230321142841055

image-20230321150420144

事务

image-20230321150846522

image-20230321151529923

image-20230321152037537

image-20230321152210277

image-20230321152738954

image-20230321152911839

查看隔离级别 select @@tx_isolation

设置隔离级别 set session transaction isolation level 后跟隔离级别

image-20230321154312367

image-20230321154715458

存储引擎

image-20230321155207155

image-20230321155426283

image-20230321155609385

image-20230321160313113

视图

image-20230321160916222

image-20230321160930825

image-20230321161129616

image-20230321161622167

视图可以在创建视图

image-20230321161731297

用户管理

image-20230321162311040

image-20230321162801172

image-20230321162733036

image-20230321162947873

image-20230321163039649

image-20230321163226369

image-20230321163329074

image-20230321163934248

JDBC和数据库连接池

image-20230321165220112

image-20230321165157232

image-20230321165614584

image-20230321165755400

image-20230323142135952

image-20230323142406049

image-20230323142721032

image-20230323143335743

用反射机制时,底层有个静态代码块完成了对驱动的注册,这是用的比较多的

image-20230323143645948

将url,user ,password等写入配置文件,让连接更灵活

image-20230323145136357

resultSet结果集,返回类似一张表的查询记录,是一个对象

image-20230323144423321

image-20230323145112811

image-20230323145320526

image-20230323150218540

image-20230323150325606

image-20230323150553771

image-20230323151459726

image-20230323151539071

image-20230323153435837

image-20230323154804215

image-20230323155221793

image-20230323155738030

image-20230323164323968

image-20230323164655789

image-20230327145232573

image-20230327145720749

image-20230327150946216

image-20230327150925100

引出数据库的实体类
image-20230327152448312

image-20230327152409711

image-20230327153404168

image-20230327153948025

参数列表中的1是赋值给sql中的?,是个可变参数,可以多个赋值

image-20230327161254146

image-20230327161641380

image-20230327162706060

image-20230327165801104

image-20230327165910576

image-20230327165929366

image-20230327163408865

image-20230327163943114

正则表达式

image-20230327170753002

image-20230327170953271

image-20230327171328313

image-20230327172043566

image-20230327172110160

image-20230327172418170

image-20230327172643116

image-20230329140708533

image-20230329142411381

image-20230329142738330

image-20230329143109036

image-20230329143220653

image-20230329143548331

image-20230329143652046

image-20230329144734495

image-20230329144827560

image-20230329145040728

image-20230329150523471

image-20230329150508456

image-20230329151136096

image-20230329153017203

image-20230329153151380

当.?*等出现在中括号中时,不用转义

image-20230329154633201

image-20230329154723976

image-20230329155951018

matches方法用于整体匹配是否成功不保存匹配结果,只返回匹配成功与否,且不需要限定符。

image-20230329160519613

image-20230329160547014

image-20230329160825485

image-20230329161546512

image-20230329161947434

image-20230329162207659

image-20230329162230760

image-20230329162330196

image-20230329162434052

项目

模拟微信零钱通

面向过程版本简单模拟微信零钱通功能

SmallChangeSystem.java

package smallchange;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/**
 * ClassName: SmallChangeSystem <br/>
 * Description: <br/>
 * date: 2023/3/30 14:11 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class SmallChangeSystem {
    //先显示菜单
    public static void main(String[] args) {
        //控制变量
        boolean loop = true;
        //接受输入
        Scanner scanner = new Scanner(System.in);
        String choice = "";
        //用字符串存零钱通明细
        String details = "---------------零钱通明细---------------" +
                "\n操作\t\t金额\t\t时间\t\t\t\t\t\t余额";
        //余额
        double balance = 0;
        //消费金额
        double money = 0;
        //时间
        Date date = null;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm::ss");
        //保存消费操作
        String operation = "";
        do {
            System.out.println("\n===============零钱通菜单===============");
            System.out.println("\t\t\t1 零钱通明细");
            System.out.println("\t\t\t2 收益入账");
            System.out.println("\t\t\t3 消\t费");
            System.out.println("\t\t\t4 退\t出");

            System.out.println("请选择(1-4):");
            choice = scanner.next();
            switch (choice) {
                case "1":
                    System.out.println(details);
                    break;
                case "2":
                    System.out.println("收入金额:");
                    money = scanner.nextDouble();
                    if (money > 0) {
                        balance += money;
                        date = new Date();
                        details += "\n收益入账\t+" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;

                    } else {
                        System.out.println("收入金额不能小于等于零,请重新输入");
                    }
                    break;
                case "3":
                    System.out.println("输入消费金额:");
                    money = scanner.nextDouble();
                    System.out.println("消费说明:");
                    operation = scanner.next();
                    if (money > 0 && money <= balance) {
                        balance -= money;
                        date = new Date();
                        if (operation.length() <= 2)
                            details += "\n" + operation + "\t\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
                        else
                            details += "\n" + operation + "\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;

                    }else {
                        System.out.println("消费金额应该在0-"+balance);
                    }
                    break;
                case "4":
                    //定义退出标志
                    String exit = "";
                    while (true) {
                        System.out.println("是否确认退出系统(y/n):");
                        exit = scanner.next();
                        if ("y".equalsIgnoreCase(exit) || "n".equalsIgnoreCase(exit))
                            break;
                    }
                    if ("y".equalsIgnoreCase(exit))
                        loop = false;
                    break;
                default:
                    System.out.println("输入有误,请重新选择");

            }

        } while (loop);

        System.out.println("零钱通项目退出");
    }
}

进行封装后的面对对象版本

SmallChangeSystemOOP.java

package smallchange;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/**
 * ClassName: SmallChangeSystemOOP <br/>
 * Description: <br/>
 * date: 2023/3/30 15:11 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class SmallChangeSystemOOP {
    //控制变量
    boolean loop = true;
    //接受输入
    Scanner scanner = new Scanner(System.in);
    String choice = "";
    //用字符串存零钱通明细
    String details = "---------------零钱通明细---------------" +
            "\n操作\t\t金额\t\t时间\t\t\t\t\t\t余额";
    //余额
    double balance = 0;
    //消费金额
    double money = 0;
    //时间
    Date date = null;
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm::ss");
    //保存消费操作
    String operation = "";
    public void MainMenu(){
        do {
            System.out.println("\n===============零钱通菜单===============");
            System.out.println("\t\t\t1 零钱通明细");
            System.out.println("\t\t\t2 收益入账");
            System.out.println("\t\t\t3 消\t费");
            System.out.println("\t\t\t4 退\t出");

            System.out.println("请选择(1-4):");
            choice = scanner.next();
            switch (choice) {
                case "1":
                    this.detail();
                    break;
                case "2":
                    this.income();
                    break;
                case "3":
                    this.pay();
                    break;
                case "4":
                    this.exit();
                    break;
                default:
                    System.out.println("输入有误,请重新选择");

            }

        } while (loop);

    }
    public void detail(){
        System.out.println(details);
    }
    public void income(){
        System.out.println("收入金额:");
        money = scanner.nextDouble();
        if (money > 0) {
            balance += money;
            date = new Date();
            details += "\n收益入账\t+" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;

        } else {
            System.out.println("收入金额不能小于等于零,请重新输入");
        }
    }
    public void pay(){
        System.out.println("输入消费金额:");
        money = scanner.nextDouble();
        System.out.println("消费说明:");
        operation = scanner.next();
        if (money > 0 && money <= balance) {
            balance -= money;
            date = new Date();
            if (operation.length() <= 2)
                details += "\n" + operation + "\t\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;
            else
                details += "\n" + operation + "\t-" + money + "\t" + simpleDateFormat.format(date) + "\t" + balance;

        }else {
            System.out.println("消费金额应该在0-"+balance);
        }
    }
    public void exit(){
        //定义退出标志
        String exit = "";
        while (true) {
            System.out.println("是否确认退出系统(y/n):");
            exit = scanner.next();
            if ("y".equalsIgnoreCase(exit) || "n".equalsIgnoreCase(exit))
                break;
        }
        if ("y".equalsIgnoreCase(exit))
            this.loop = false;
    }

}

SmallChangeSystemApp.java进行调用

package smallchange;

/**
 * ClassName: SmallChangeSystemApp <br/>
 * Description: <br/>
 * date: 2023/3/30 15:11 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
public class SmallChangeSystemApp {
    public static void main(String[] args) {
        SmallChangeSystemOOP smallChangeSystemOOP = new SmallChangeSystemOOP();
        smallChangeSystemOOP.MainMenu();
    }
}

房屋出租系统

HouseRentApp.java

package houserent;

import houserent.view.HouseView;

/**
 * ClassName: HouseRentApp <br/>
 * Description: <br/>
 * date: 2023/3/30 17:58 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
public class HouseRentApp {
    public static void main(String[] args) {
        //程序的入口
        HouseView houseView = new HouseView();
        houseView.mainMenu();
        System.out.println("退出了房屋出租系统");

    }
}

House.java

package houserent.domain;

/**
 * ClassName: House <br/>
 * Description: House的一个对象表示一个房屋信息
 * date: 2023/3/30 18:04 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
public class House {
    private int id;
    private String name;
    private String phone;
    private String address;
    private int rent;
    private String state;

    public House(int id, String name, String phone, String address, int rent, String state) {
        this.id = id;
        this.name = name;
        this.phone = phone;
        this.address = address;
        this.rent = rent;
        this.state = state;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getRent() {
        return rent;
    }

    public void setRent(int rent) {
        this.rent = rent;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public String toString() {
        return  id +
                "\t\t" + name +
                "\t" + phone  +
                "\t\t" + address  +
                "\t" + rent +
                "\t" + state ;
    }
}

HouseView.java

package houserent.view;

import houserent.domain.House;
import houserent.service.HouseService;
import houserent.utils.Utility;

import java.util.Scanner;

/**
 * ClassName: HouseView <br/>
 * Description: 1. 显示界面
 * 2.接收用户输入
 * 3.调用HouseService完成对房屋信息的操作
 * date: 2023/3/30 18:10 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class HouseView {
    //菜单显示控制变量
    private boolean loop = true;
    //用户输入
    private char key = ' ';
    //初始的House数组大小
    private HouseService houseService = new HouseService(2);

    public void mainMenu() {
        do {
            System.out.println("===============房屋出租系统菜单===============");
            System.out.println("\t\t\t1 新 增 房 源");
            System.out.println("\t\t\t2 查 找 房 屋");
            System.out.println("\t\t\t3 删 除 房 屋 信 息");
            System.out.println("\t\t\t4 修 改 房 屋 信 息");
            System.out.println("\t\t\t5 房 屋 列 表");
            System.out.println("\t\t\t6 退       出");
            System.out.println("请输入你的选择:");
            key = Utility.readChar();
            switch (key) {
                case '1':
                    addHouse();
                    break;
                case '2':
                    findHouse();
                    break;
                case '3':
                    deleteHouse();
                    break;
                case '4':
                    updateHouse();
                    break;
                case '5':
                    listHouses();
                    break;
                case '6':
                    exit();
                    break;

            }

        } while (loop);
    }

    //显示房屋列表
    public void listHouses() {
        System.out.println("===============房屋列表===============");
        System.out.println("编号\t\t房主\t\t电话\t\t地址\t\t月租\t\t状态(未出租/已出租)");
        House[] list = houseService.list();
        for (House house : list) {
            if (house != null)
                System.out.println(house);
        }
        System.out.println("=============房屋列表显示完毕=============");

    }

    public void addHouse() {
        System.out.println("===============添加房屋===============");
        System.out.println("姓名:");
        String name = Utility.readString(8);
        System.out.println("电话:");
        String phone = Utility.readString(12);
        System.out.println("地址:");
        String address = Utility.readString(16);
        System.out.println("月租:");
        int rent = Utility.readInt();
        System.out.println("状态:");
        String state = Utility.readString(3);
        //创建一个house对象,id自增长
        House house = new House(0, name, phone, address, rent, state);
        if (houseService.add(house))
            System.out.println("===============添加房屋成功===============");
        else
            System.out.println("===============添加房屋失败===============");

    }

    public void deleteHouse() {
        System.out.println("===============删除房屋信息===============");
        System.out.println("请输入待删除房屋的编号(-1退出):");
        int deleteId = Utility.readInt();
        if (deleteId == -1) {
            System.out.println("放弃删除房屋信息");
            return;
        }
        char choice = Utility.readConfirmSelection();
        if (choice == 'Y') {
            if (houseService.delete(deleteId)) {
                System.out.println("===============删除房屋成功===============");
            } else {
                System.out.println("===============删除房屋失败,编号不存在===============");
            }

        } else {
            System.out.println("===============放弃删除房屋===============");
        }

    }

    public void exit() {
        char c = Utility.readConfirmSelection();
        if (c == 'Y') loop = false;
    }

    public void findHouse() {
        System.out.println("请输入你要查找的房屋ID:");
        int findId = Utility.readInt();
        House house = houseService.findById(findId);
        if (house != null) {
            System.out.println(house);
        } else {
            System.out.println("===============查找的房屋ID不存在===============");
        }

    }

    public void updateHouse() {
        System.out.println("请输入你要修改的房屋ID(-1退出):");
        int updId = Utility.readInt();
        if (updId == -1) {
            System.out.println("===============放弃修改房屋信息===============");
            return;

        }
        House house = houseService.findById(updId);
        if (house == null) {
            System.out.println("===============修改房屋ID不存在===============");
            return;
        }
        System.out.println("姓名(" + house.getName() + "):");
        String name = Utility.readString(8, "");
        if (!name.equals("")) {
            house.setName(name);
        }
        System.out.println("电话(" + house.getPhone() + "):");
        String phone = Utility.readString(12, "");
        if (!phone.equals("")) {
            house.setPhone(phone);
        }
        System.out.println("地址(" + house.getAddress() + "):");
        String address = Utility.readString(16, "");
        if (!address.equals("")) {
            house.setAddress(address);
        }
        System.out.println("租金(" + house.getRent() + "):");
        int rent = Utility.readInt(-1);
        if (rent != -1) {
            house.setRent(rent);
        }
        System.out.println("状态("+house.getState()+"):");
        String state = Utility.readString(3, "");
        if(!state.equals("")){
            house.setState(state);
        }
        System.out.println("===============修改房屋信息成功===============");

    }
}

HouseService.java

package houserent.service;

import houserent.domain.House;

/**
 * ClassName: HouseService <br/>
 * Description: 响应HouseView的调用
 * 完成对房屋信息的crud
 * date: 2023/3/30 18:35 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class HouseService {
    private House[] houses;
    private int housenum = 1; //记录有多少房屋
    private int idcounter = 1;//记录id增长

    //通过size指定生成的House[]数组大小
    public HouseService(int size) {
        houses = new House[size];
        houses[0] = new House(1, "jack", "154611", "徐州", 1500, "未出租");

    }

    public House[] list() {
        return houses;
    }

    //房屋信息添加
    public boolean add(House house) {
        if (housenum == houses.length) {
            int newSize = (int) (housenum * 1.5);
            House[] temp = new House[newSize];
            for (int i = 0; i < housenum; i++) {
                temp[i] = houses[i];
            }
            houses = temp;
            System.out.println("已经扩容");
        }
        houses[housenum++] = house;//加house数组
        //同时更新刚加入的房屋id
        house.setId(++idcounter);
        return true;
    }

    //房屋信息删除
    public boolean delete(int delId) {
        int index = -1;//记录delId对应的下标
        for (int i = 0; i < housenum; i++){
            if(houses[i].getId() == delId){
                index = i;
            }
        }
        if(index == -1)
            return false;
        for(int i =index;i<housenum-1;i++){
            houses[i]=houses[i+1];
        }
        houses[--housenum] = null;//当前有存在的房屋信息最后一个置为null
        return true;

    }
    public House findById(int findId){
        for(int i=0;i<housenum;i++){
            if(findId == houses[i].getId())
                return houses[i];
        }
        return null;
    }

}

Utility.java

package houserent.utils;


/**
   工具类的作用:
   处理各种情况的用户输入,并且能够按照程序员的需求,得到用户的控制台输入。
*/

import java.util.*;
/**

   
*/
public class Utility {
   //静态属性。。。
    private static Scanner scanner = new Scanner(System.in);

    
    /**
     * 功能:读取键盘输入的一个菜单选项,值:1——5的范围
     * @return 1——5
     */
   public static char readMenuSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false);//包含一个字符的字符串
            c = str.charAt(0);//将字符串转换成字符char类型
            if (c != '1' && c != '2' && 
                c != '3' && c != '4' && c != '5') {
                System.out.print("选择错误,请重新输入:");
            } else break;
        }
        return c;
    }

   /**
    * 功能:读取键盘输入的一个字符
    * @return 一个字符
    */
    public static char readChar() {
        String str = readKeyBoard(1, false);//就是一个字符
        return str.charAt(0);
    }
    /**
     * 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符
     * @param defaultValue 指定的默认值
     * @return 默认值或输入的字符
     */
    
    public static char readChar(char defaultValue) {
        String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符
        return (str.length() == 0) ? defaultValue : str.charAt(0);
    }
   
    /**
     * 功能:读取键盘输入的整型,长度小于2位
     * @return 整数
     */
    public static int readInt() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(10, false);//一个整数,长度<=2位
            try {
                n = Integer.parseInt(str);//将字符串转换成整数
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }
    /**
     * 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数
     * @param defaultValue 指定的默认值
     * @return 整数或默认值
     */
    public static int readInt(int defaultValue) {
        int n;
        for (; ; ) {
            String str = readKeyBoard(10, true);
            if (str.equals("")) {
                return defaultValue;
            }
         
         //异常处理...
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }

    /**
     * 功能:读取键盘输入的指定长度的字符串
     * @param limit 限制的长度
     * @return 指定长度的字符串
     */

    public static String readString(int limit) {
        return readKeyBoard(limit, false);
    }

    /**
     * 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串
     * @param limit 限制的长度
     * @param defaultValue 指定的默认值
     * @return 指定长度的字符串
     */
   
    public static String readString(int limit, String defaultValue) {
        String str = readKeyBoard(limit, true);
        return str.equals("")? defaultValue : str;
    }


   /**
    * 功能:读取键盘输入的确认选项,Y或N
    * 将小的功能,封装到一个方法中.
    * @return Y或N
    */
    public static char readConfirmSelection() {
        System.out.println("请输入你的选择(Y/N)");
        char c;
        for (; ; ) {//无限循环
           //在这里,将接受到字符,转成了大写字母
           //y => Y n=>N
            String str = readKeyBoard(1, false).toUpperCase();
            c = str.charAt(0);
            if (c == 'Y' || c == 'N') {
                break;
            } else {
                System.out.print("选择错误,请重新输入:");
            }
        }
        return c;
    }

    /**
     * 功能: 读取一个字符串
     * @param limit 读取的长度
     * @param blankReturn 如果为true ,表示 可以读空字符串。 
     *                   如果为false表示 不能读空字符串。
     *           
    * 如果输入为空,或者输入大于limit的长度,就会提示重新输入。
     * @return
     */
    private static String readKeyBoard(int limit, boolean blankReturn) {
        
      //定义了字符串
      String line = "";

      //scanner.hasNextLine() 判断有没有下一行
        while (scanner.hasNextLine()) {
            line = scanner.nextLine();//读取这一行
           
         //如果line.length=0, 即用户没有输入任何内容,直接回车
         if (line.length() == 0) {
                if (blankReturn) return line;//如果blankReturn=true,可以返回空串
                else continue; //如果blankReturn=false,不接受空串,必须输入内容
            }

         //如果用户输入的内容大于了 limit,就提示重写输入  
         //如果用户如的内容 >0 <= limit ,我就接受
            if (line.length() < 1 || line.length() > limit) {
                System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");
                continue;
            }
            break;
        }

        return line;
    }
}

坦克大战

其中涉及到爆炸的三张图片,以及音效文件,网上素材应该很多,有需要的私信我或下方评论我给你发。

MyTankGame.java 启动游戏

package tankgame;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;

/**
 * ClassName: MyTankGame <br/>
 * Description: <br/>
 * date: 2023/4/2 5:54 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class MyTankGame extends JFrame {
    MyPanel myPanel = null;
    Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {

        MyTankGame myTankGame = new MyTankGame();

    }
    public MyTankGame(){
        System.out.println("请输入你的选择1:新游戏 2:继续上局游戏");
        String key = scanner.next();
        myPanel = new MyPanel(key);
        new Thread(myPanel).start();
        this.add(myPanel);//把面板放入
        this.setSize(1300,950);
        this.addKeyListener(myPanel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        //增加相应关闭窗口的监听器
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                Recorder.keepRecord();
                System.exit(0);
            }
        });
    }
}

Tank.java 坦克父类

package tankgame;

/**
 * ClassName: Tank <br/>
 * Description: tank父类
 * date: 2023/4/2 5:49 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class Tank {
    private int x;//坦克横坐标
    private int y;//坦克纵坐标
    private int direct;//坦克方向
    private int speed;//坦克速度
    private boolean isLive = true;//坦克存活

    public boolean isLive() {
        return isLive;
    }

    public void setLive(boolean live) {
        isLive = live;
    }

    public void moveUp() {
        y -= speed;
    }

    public void moveRight() {
        x += speed;
    }

    public void moveDown() {
        y += speed;
    }

    public void moveLeft() {
        x -= speed;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        this.direct = direct;
    }

    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;
    }
}

MyTank.java 玩家操控的tank对象

package tankgame;

import java.util.Vector;

/**
 * ClassName: MyTank <br/>
 * Description: <br/>
 * date: 2023/4/2 5:50 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class MyTank extends Tank{
    //定义一个shot对象,对应射击行为
    Shot shot = null;
    //发射多颗子弹,用Vector存储
    Vector<Shot> shots = new Vector<>();
    public MyTank(int x, int y) {
        super(x, y);
    }
    public void shotEnemy(){
        if(shots.size() == 10){
            return;
        }
        //子弹方向要和当前MyTank对象一致
        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.add(shot);
        new Thread(shot).start();
    }
}

EnemyTank.java 敌人tank

package tankgame;

import java.util.Vector;

/**
 * ClassName: EnemyTank <br/>
 * Description: 敌人的坦克
 * date: 2023/4/3 11:55 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class EnemyTank extends Tank implements Runnable {
    //敌人坦克的子弹集合
    Vector<Shot> shots = new Vector<>();
    //存储所有敌方坦克的Vector
    Vector<EnemyTank> enemyTanks = new Vector<>();

    public EnemyTank(int x, int y) {
        super(x, y);
    }

    public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        this.enemyTanks = enemyTanks;
    }

    //判断当前的敌人坦克是否和其他敌人坦克碰撞
    public boolean isTouchEnemyTank() {
        //判断当前敌人坦克方向
        switch (getDirect()) {
            case 0:
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //如果敌人是上下方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
                        //当前坦克坐标左上角[this.getX(),this.getY()]
                        //当前坦克坐标右上角[this.getX()+40,this.getY()]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }

                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人是左右方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }

                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case 1:
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //如果敌人是上下方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
                        //当前坦克坐标右上角[this.getX()+60,this.getY()]
                        //当前坦克坐标右下角[this.getX()+60,this.getY()+40]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }

                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 40
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人是左右方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }

                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 60
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case 2:
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //如果敌人是上下方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
                        //当前坦克坐标左下角[this.getX(),this.getY()+60]
                        //当前坦克坐标右下角[this.getX()+40,this.getY()+60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 60) {
                                return true;
                            }

                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 40
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人是左右方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 40) {
                                return true;
                            }

                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case 3:
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    if (this != enemyTank) {
                        //如果敌人是上下方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+40]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+60]
                        //当前坦克坐标左上角[this.getX(),this.getY()]
                        //当前坦克坐标左下角[this.getX(),this.getY()+40]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }

                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人是左右方向
                        //1.敌人坦克范围x[enemyTank.getX(),enemyTank.getX()+60]
                        //2.敌人坦克范围y[enemyTank.getY(),enemyTank.getY()+40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }

                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
                break;
        }
        return false;
    }

    @Override
    public void run() {
        while (true) {
            //发射多颗子弹
            if (shots.size() <= 5 && isLive()) {
                //子弹方向要和当前MyTank对象一致
                Shot shot = null;
                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.add(shot);
                new Thread(shot).start();
            }
            //进行随机移动且避免碰撞
            switch (getDirect()) {
                case 0:
                    for (int i = 0; i < 20; i++) {
                        if (getY() > 0 && !isTouchEnemyTank()) {
                            moveUp();
                        }
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 1:
                    for (int i = 0; i < 20; i++) {
                        if (getX() + 60 < 1000 && !isTouchEnemyTank()) {
                            moveRight();
                        }
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2:
                    for (int i = 0; i < 20; i++) {
                        if (getY() + 60 < 750 && !isTouchEnemyTank()) {
                            moveDown();
                        }
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 3:
                    for (int i = 0; i < 20; i++) {
                        if (getX() > 0 && !isTouchEnemyTank()) {
                            moveLeft();
                        }
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }

            setDirect((int) (Math.random() * 4));
            if (!isLive()) {
                break;
            }
        }
    }
}

Shot.java 描述子弹的类

package tankgame;

/**
 * ClassName: Shot <br/>
 * Description: 子弹类
 * date: 2023/4/3 13:58 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class Shot implements Runnable{
    private int x;
    private int y;
    private int direct;
    private int speed = 2;
    private boolean isLive = true;

    public Shot(int x, int y, int direct) {
        this.x = x;
        this.y = y;
        this.direct = direct;
    }

    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 int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public boolean isLive() {
        return isLive;
    }

    public void setLive(boolean live) {
        isLive = live;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            switch (direct){
                case 0:
                    y-=speed;
                    break;
                case 1:
                    x+=speed;
                    break;
                case 2:
                    y+=speed;
                    break;
                case 3:
                    x-=speed;
                    break;
            }
            if(!(x >= 0 && x<= 1000 && y>=0 && y<=750 && isLive)){
                isLive = false;
                break;
            }
        }
    }
}

MyPanel.java 主要界面

package tankgame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;

/**
 * ClassName: MyPanel <br/>
 * Description: 主要界面
 * date: 2023/4/2 5:51 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class MyPanel extends JPanel implements KeyListener, Runnable {
    //定义我的坦克
    MyTank myTank = null;
    Vector<EnemyTank> enemyTanks = new Vector<>();
    Vector<Node> nodes = new Vector<>();
    int enemyTankSize = 5;
    Vector<Bomb> bombs = new Vector<>();
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    public MyPanel(String key) {
        File file = new File(Recorder.getRecordFile());
        if(file.exists()) {
            nodes = Recorder.getNodesAndEnemyTankRecord();
        }else{
            System.out.println("上局游戏不存在,开始新游戏");
            key = "1";
        }
        Recorder.setEnemyTanks(enemyTanks);
        myTank = new MyTank(400, 300);//初始化位置
        myTank.setSpeed(10);

        switch (key){
            case "1":
                for (int i = 0; i < enemyTankSize; i++) {
                    EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
                    enemyTank.setDirect(2);
                    enemyTank.setSpeed(3);
                    enemyTank.setEnemyTanks(enemyTanks);
                    enemyTanks.add(enemyTank);
                    new Thread(enemyTank).start();
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    enemyTank.shots.add(shot);
                    new Thread(shot).start();
                }
                break;
            case "2":
                for (int i = 0; i < nodes.size(); i++) {
                    Node node = nodes.get(i);
                    EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
                    enemyTank.setDirect(node.getDirect());
                    enemyTank.setSpeed(3);
                    enemyTank.setEnemyTanks(enemyTanks);
                    enemyTanks.add(enemyTank);
                    new Thread(enemyTank).start();
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    enemyTank.shots.add(shot);
                    new Thread(shot).start();
                }
        }
        for (int i = 0; i < enemyTankSize; i++) {
            EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
            enemyTank.setDirect(2);
            enemyTank.setSpeed(3);
            enemyTank.setEnemyTanks(enemyTanks);
            enemyTanks.add(enemyTank);
            new Thread(enemyTank).start();
            Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
            enemyTank.shots.add(shot);
            new Thread(shot).start();
        }

        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));

        new AePlayWave("src\\111.wav").start();
    }

    //编写方法,提示击毁坦克的信息
    public void showInfo(Graphics g){
        g.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 25);
        g.setFont(font);
        g.drawString("您累积击毁敌方坦克",1020,30);
        drawTank(1020,60,g,0,1);
        g.setColor(Color.BLACK);
        g.drawString(Recorder.getAllEnemyTankNum()+"",1080,100);
    }
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);//填充矩形
        showInfo(g);
        if(myTank.isLive() && myTank !=null) {
            drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirect(), 0);
        }
        for (int i = 0; i < myTank.shots.size(); i++) {
            Shot shot = myTank.shots.get(i);
            if (shot != null && shot.isLive()) {
                g.draw3DRect(shot.getX(), shot.getY(), 1, 1, false);
            } else {
                myTank.shots.remove(shot);
            }
        }

        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            if (enemyTank.isLive() && enemyTank != null) {
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
                for (int j = 0; j < enemyTank.shots.size(); j++) {
                    Shot shot = enemyTank.shots.get(j);
                    if (shot.isLive() && shot != null) {
                        g.draw3DRect(shot.getX(), shot.getY(), 1, 1, false);
                    } else {
                        enemyTank.shots.remove(shot);
                    }
                }
            } else {
                enemyTanks.remove(enemyTank);
            }
        }
        for (int i = 0; i < bombs.size(); i++) {
            Bomb bomb = bombs.get(i);
            if (bomb.getLife() > 6) {
                g.drawImage(image1, bomb.getX(), bomb.getY(), 60, 60, this);
            } else if (bomb.getLife() > 3) {
                g.drawImage(image2, bomb.getX(), bomb.getY(), 60, 60, this);
            } else {
                g.drawImage(image3, bomb.getX(), bomb.getY(), 60, 60, this);
            }
            bomb.lifeDown();
            if (bomb.getLife() == 0) {
                bombs.remove(bomb);
            }
        }

    }
    //编写方法,画出坦克

    /**
     * @param x      坦克左上角的x坐标
     * @param y      坦克左上角的y坐标
     * @param g      画笔
     * @param direct 坦克朝向
     * @param type   坦克类型
     */
    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;
            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;
        }

    }

    public void hitTank(Shot shot, Tank tank) {
        switch (tank.getDirect()) {
            case 0:
            case 2:
                if (shot.getX() >= tank.getX() && shot.getX() <=
                        tank.getX() + 40 && shot.getY() >= tank.getY()
                        && shot.getY() <= tank.getY() + 60) {
                    shot.setLive(false);
                    tank.setLive(false);
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                    if(tank instanceof EnemyTank){
                        enemyTanks.remove(tank);
                        Recorder.addAllEnemyTankNum();
                    }

                }
                break;
            case 1:
            case 3:
                if (shot.getX() >= tank.getX() && shot.getX() <=
                        tank.getX() + 60 && shot.getY() >= tank.getY()
                        && shot.getY() <= tank.getY() + 40) {
                    shot.setLive(false);
                    tank.setLive(false);
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                    if(tank instanceof EnemyTank){
                        enemyTanks.remove(tank);
                        Recorder.addAllEnemyTankNum();;
                    }
                }
                break;
        }
    }

    public void hitEnemyTank(){
        for (int i = 0; i < myTank.shots.size(); i++) {
            Shot shot = myTank.shots.get(i);
            if (shot != null && shot.isLive()) {
                for (int j = 0;j<enemyTanks.size();j++) {
                    EnemyTank enemyTank = enemyTanks.get(j);
                    hitTank(shot, enemyTank);
                }
            }
        }
    }

    public void hitMyTank(){
        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 (shot.isLive() && myTank.isLive()){
                        hitTank(shot,myTank);
                    }
                }

        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键
            System.out.println((char) e.getKeyCode());
            myTank.setDirect(0);
            if (myTank.getY() > 0) {
                myTank.moveUp();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_D) {
            System.out.println((char) e.getKeyCode());
            myTank.setDirect(1);
            if (myTank.getX() + 60 < 1000) {
                myTank.moveRight();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_S) {
            System.out.println((char) e.getKeyCode());
            myTank.setDirect(2);
            if (myTank.getY() + 60 < 750) {
                myTank.moveDown();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_A) {
            System.out.println((char) e.getKeyCode());
            myTank.setDirect(3);
            if (myTank.getX() > 0) {
                myTank.moveLeft();
            }
        }

        if (e.getKeyCode() == KeyEvent.VK_J) {
            /**发射一颗子弹的情况
             * if(myTank.shot == null || !myTank.shot.isLive()) {
             *                 myTank.shotEnemy();
             *             }
             */
            myTank.shotEnemy();

        }

        this.repaint();

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            hitMyTank();
            hitEnemyTank();

            this.repaint();
        }
    }
}

Node.java 存储敌人位置方向,用于恢复实现继续上局游戏

package tankgame;

/**
 * ClassName: Node <br/>
 * Description: 一个node对象表示一个敌人坦克的信息
 * date: 2023/4/6 0:10 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
public class Node {
    private int x;
    private int y;
    private int direct;

    public Node(int x, int y, int direct) {
        this.x = x;
        this.y = y;
        this.direct = direct;
    }

    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;
    }
}

Recorder.java 与文件进行交互,记录相关信息

package tankgame;

import java.io.*;
import java.util.Vector;

/**
 * ClassName: Recoder <br/>
 * Description: 该类用于记录相关信息和文件进行交互
 * date: 2023/4/5 18:26 <br/>
 *
 * @author Mr.Shen <b/r>
 * @since JDK 8
 */
@SuppressWarnings({"all"})
public class Recorder {
    private static int allEnemyTankNum = 0;
    private static BufferedReader bufferedReader = null;
    private static BufferedWriter bufferedWriter = null;
    private static String recordFile = "src\\myRecord.txt";
    private static Vector<EnemyTank> enemyTanks = null;
    private static Vector<Node> nodes = new Vector<>();

    public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        Recorder.enemyTanks = enemyTanks;
    }

    public static int getAllEnemyTankNum() {
        return allEnemyTankNum;
    }

    public static void setAllEnemyTankNum(int allEnemyTankNum) {
        Recorder.allEnemyTankNum = allEnemyTankNum;
    }

    public static void addAllEnemyTankNum() {
        Recorder.allEnemyTankNum++;
    }

    public static String getRecordFile() {
        return recordFile;
    }

    public static void keepRecord() {
        try {
            bufferedWriter = new BufferedWriter(new FileWriter(recordFile));
            bufferedWriter.write(Recorder.getAllEnemyTankNum() + "\r\n");
            for (int i = 0; i < enemyTanks.size(); i++) {
                EnemyTank enemyTank = enemyTanks.get(i);
                if (enemyTank.isLive()) {
                    String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();
                    bufferedWriter.write(record + "\r\n");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //增加一个信息用于读取recordFile,恢复相关信息
    public static Vector<Node> getNodesAndEnemyTankRecord(){
        try {
            bufferedReader = new BufferedReader(new FileReader(recordFile));
            allEnemyTankNum = Integer.parseInt(bufferedReader.readLine());
            String line = "";
            while ((line = bufferedReader.readLine()) != null){
                String[] s = line.split(" ");
                Node node = new Node(Integer.parseInt(s[0]),
                        Integer.parseInt(s[1]),
                        Integer.parseInt(s[2]));
                nodes.add(node);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bufferedReader != null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return nodes;
    }
}

韩老师的音屏处理类

package tankgame;

import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;

/**
 * @author 韩顺平
 * @version 1.0
 */
public class AePlayWave extends Thread {
    private String filename;

    public AePlayWave(String wavfile) {
        filename = wavfile;

    }

    public void run() {

        File soundFile = new File(filename);

        AudioInputStream audioInputStream = null;
        try {
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        } catch (Exception e1) {
            e1.printStackTrace();
            return;
        }

        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

        try {
            auline = (SourceDataLine) AudioSystem.getLine(info);
            auline.open(format);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        auline.start();
        int nBytesRead = 0;
        //这是缓冲
        byte[] abData = new byte[512];

        try {
            while (nBytesRead != -1) {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0)
                    auline.write(abData, 0, nBytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } finally {
            auline.drain();
            auline.close();
        }

    }
}

设计模式

单例设计模式

image-20221225132629137

image-20221225133450085

懒汉式

image-20221225134000527

image-20221225134155922

模板模式

将重复代码提取到共同的父类,并声明为抽象类,子类继承并实现不同的方法

image-20230110155339679

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值