java基础练习缺少项目?看这篇文章就够了(上)!
公众号:全干开发 。 专注分享简洁但高质量的动图技术文章!
项目概述
本教程适合刚学习完java基础语法的同学,涉及if语句、循环语句、类的封装、集合等基础概念,使用大量gif图帮助读者演示代码操作、效果等,是一个非常不错的巩固练习教程!不涉及任何java框架等内容,可以放心食用!
本教程将使用控制台模拟一个ATM取款机!
基础需求演示
ATM机主要有用户开户、用户登录(登录后可以转账等)功能,我们简单演示一下用户开户功能!

系统架构
根据我们的需求,我们可以知道,我们的这个程序应该主要包含两个类
- 账户类Account:包含卡号、姓名、性别、密码、余额、额度等属性
- ATM类:代表ATM系统,负责提供业务需求,具备欢迎页、转账、开通账户等功能
项目搭建
创建项目
打开编译器,创建名为Project_ATM的项目

创建Account类
Account类用来表示账户信息,包含卡号、姓名、性别、密码、余额、额度等属性,我们创建这个类,并完善一些基本属性

Acount的基本属性创建完毕后,我们需要给这些属性创建get和set方法,用来方便快捷的更改和读取这些数值。
我们使用IDEA的快捷操作:
光标放在Account类内部,右键点击【Generate】,点击【Getter and Setter】,点住ctrl键不放,选中Acoount的所有属性,点击【ok】即可

生成的代码如下:
public class Account {private String cardId; // 卡号private String userName; // 名称private char sex; // 性别private String passWord; // 密码private double money; // 资产private double limit; // 限额public String getCardId() {return cardId;}public void setCardId(String cardId) {this.cardId = cardId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public String getPassWord() {return passWord;}public void setPassWord(String passWord) {this.passWord = passWord;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}public double getLimit() {return limit;}public void setLimit(double limit) {this.limit = limit;}
}
创建ATM类
ATM类用来模拟ATM系统的一些功能,最重要的,它应该能储存不同用户的账户信息(accounts),并且这个账户信息应该是私有的(private),不能随便被访问到。
我们创建这个类,并定义好所有用户的信息集合 accounts

import java.util.ArrayList;public class ATM {private ArrayList<Account> accounts = new ArrayList<>();
}
我们的欢迎页是在控制台显示的,长下面这个样子

我们用代码实现一下这个逻辑
import java.util.ArrayList;
import java.util.Scanner;public class ATM {private ArrayList<Account> accounts = new ArrayList<>();// 创建一个新的Scanner对象,名为sc。Scanner对象用于获取用户键盘输入的值。private Scanner sc = new Scanner(System.in);public void start(){System.out.println("===欢迎您进入到了ATM系统===");System.out.println("1、用户登录");System.out.println("2、用户开户");System.out.println("请选择:");// 调用nextInt()方法,等待用户输入一个整数,并将这个整数存储在变量command中。int command = sc.nextInt();switch (command) {case 1://用户登录break;case 2://用户开户break;default:System.out.println("操作错误!");// 输入错误重新进入开始页start();}}
}
现在,我们可以测试一下了。
创建Test类
想要验证我们的ATM功能是否ok,我们需要创建个Test类验证下:

public class Text {public static void main(String[] args) {// 创建atm类,代表一个ATM系统ATM atm = new ATM();//启动ATM系统atm.start();}
}
我们执行这个函数试试效果
不错,很完美!
开户功能完善
功能简介
开户功能就是新增一个账户,也就是向系统的账户集合添加一个账户对象, 这个账户对象应该包含用户输入的姓名、性别、密码及每次取现的额度信息;同时,还有一个系统生成的随机卡号(8位数字,不能重复)。
生成基础信息
我们在ATM类中创建一个开户操作createAccount方法
public class ATM {private ArrayList<Account> accounts = new ArrayList<>();// 创建一个新的Scanner对象,名为sc。Scanner对象用于获取用户键盘输入的值。private Scanner sc = new Scanner(System.in);public void start(){// .....}// 用户开户操作private void createAccount(){}
}
这个createAccount方法应该做三件事儿:
- 创建一个账户对象,用于封装用户的开户信息
- 需要用户输入自己的开户信息,赋值给账户对象
- 把这个账户对象,存入到账户集合中去
第二步中,我们首先需要用户输入账户名称
private void createAccount(){// 1、创建一个账户对象,用于封装用户的开户信息Account account = new Account();// 2、需要用户输入自己的开户信息,赋值给账户对象System.out.println("请您输入您的账户名称:");String name = sc.next() ;account.setUserName(name);// 3、把这个账户对象,存入到账户集合中去}
sc.next()用于输出字符串
然后,需要用户输入性别
// 2、需要用户输入自己的开户信息,赋值给账户对象// ....System.out.println("请输入性别");
char sex = sc.next().charAt(0);
if (sex == '男' || sex == '女') {account.setSex(sex);
} else {System.out.println("输入无效,请输入男或女。");
}// 3、把这个账户对象,存入到账户集合中去
注意:我们在Account类中定义性别用的是基本类型char,所以这里的sex用 char修饰。sc.next()返回的是字符串String类,所以我们用charAt(0)获取到这个字符串的第一个字符,将其转换成了char类型
上述代码中,如果用户没有按照我们的预期输入性别,我们应该让它重新输入,所以需要循环这部分代码。我们借助编译器添加while循环语句:选中代码,点击crtl+alt+T,选择while;if语句中,我们需要终止循环

最后,我们完善下其他方法
// 用户开户操作private void createAccount(){// 1、创建一个账户对象,用于封装用户的开户信息Account account = new Account();// 2、需要用户输入自己的开户信息,赋值给账户对象System.out.println("请您输入您的账户名称:");// sc.next()用于返回字符串String name = sc.next() ;account.setUserName(name);while (true) {System.out.println("请输入性别");char sex = sc.next().charAt(0);if (sex == '男' || sex == '女') {account.setSex(sex);break;} else {System.out.println("输入无效,请输入男或女。");}}while (true){System.out.println("请您输入您的账户密码:");String passWord = sc.next();System.out.println("请您输入您的确认密码:");String okPassWord = sc.next();// 判断2次密码是否一样。if(okPassWord.equals(passWord)) {account.setPassWord(okPassWord);break;} else {System.out.println("您输入的2次密码不一致,请您确认~~");}}System.out.println("请您输入您的取现额度:");double limit = sc.nextDouble();account.setLimit(limit);// 3、把这个账户对象,存入到账户集合中去
注:卡号的生成比较复杂,我们先暂时忽略
现在,我们进行第三步,把生成的账户对象,存入到账户集合中。
// 3、把这个账户对象,存入到账户集合中去
accounts.add(account);
System.out.println("恭喜您,"+ account.getUserName() + "开户成功,您的卡号是:");
我们在Account类中完善一下getUserName方法
public String getUserName() {return userName + ( sex == '男' ? "先生": "女士");
}
OK,现在我们在start方法中运行下createAccount()方法

然后再Tset类中运行程序试试看
丝滑流畅!
生长卡号信息
卡号是一个8位的数字,且和已有卡号不能重复,它的创建分为以下几个步骤
定义一个string类型的变量记住8位数字作为一个卡号
String cardId = "";
使用循环,循环8次,每次产生一个随机数给cardId连接起来
Random r = new Random();
for (int i = ; i < 8; i++) {int data = r.nextInt( bound: 10); // 0 - 9cardId += data;
}
判断cardId中记住的卡号,是否与其他账户的卡号重复了,没有重复,才可以做为一个新卡号返回.
Account acc = getAccountByCardId(cardId);
if(acc == null){// 说明cardId没有找到账户对象,因此cardId没有与其他账户的卡号重复,可以返回它做为一个新卡号return cardId;
}
详细代码如下
public void start(){ ... }// 用户开户操作private void createAccount(){ ... }// 返回一个8位 数字的卡号,而且这个卡号不能与其他账户的卡号重复private String createCardId(){while (true) {String cardId = "";Random r = new Random();for (int i = 0; i < 8; i++) {int data = r.nextInt(10); // 0 - 9cardId += data;}// 判断cardId中记住的卡号,是否与其他账户的卡号重复了,没有重复,才可以做为一个新卡号返回.Account acc = getAccountByCardId(cardId);if(acc == null){// 说明cardId没有找到账户对象,因此cardId没有与其他账户的卡号重复,可以返回它做为一个新卡号return cardId;}}}// 根据卡号查询账户对象返回 accounts = [c1,c2,c3。]private Account getAccountByCardId(String cardId){// 遍历全部的账户对象for (int i = 0; i < accounts.size(); i++) {Account acc = accounts.get(i);// 判断这个账户对象acc 中的卡号是否是我们要找的卡号if(acc.getCardId().equals(cardId)){return acc;}}return null; // 查无此账户,这个卡号不存在的}
- get(int index):是集合特有的方法,用于返回指定位置的元素
- Random是一个类,它提供了生成各种类型的随机数的方法。
- nextInt(10)生成0-9之间的随机数
现在,我们就可以完善开户功能了!
// 用户开户操作private void createAccount(){// ...String newCard = createCardId();account.setCardId(newCard);// 3、把这个账户对象,存入到账户集合中去accounts.add(account);System.out.println("恭喜您,"+ account.getUserName() + "开户成功,您的卡号是:" + newCard);}

结语
至此,我们的开户功能就完成了!下面是开户功能的完整代码!
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;public class ATM {private ArrayList<Account> accounts = new ArrayList<>();// 创建一个新的Scanner对象,名为sc。Scanner对象用于获取用户键盘输入的值。private Scanner sc = new Scanner(System.in);public void start(){System.out.println("===欢迎您进入到了ATM系统===");System.out.println("1、用户登录");System.out.println("2、用户开户");System.out.println("请选择:");// 调用nextInt()方法,等待用户输入一个整数,并将这个整数存储在变量command中。int command = sc.nextInt();switch (command) {case 1://用户登录break;case 2://用户开户createAccount();break;default:System.out.println("操作错误!");// 输入错误重新进入开始页start();}}// 用户开户操作private void createAccount(){// 1、创建一个账户对象,用于封装用户的开户信息Account account = new Account();// 2、需要用户输入自己的开户信息,赋值给账户对象System.out.println("请您输入您的账户名称:");// sc.next()用于返回字符串String name = sc.next() ;account.setUserName(name);while (true) {System.out.println("请输入性别");char sex = sc.next().charAt(0);if (sex == '男' || sex == '女') {account.setSex(sex);break;} else {System.out.println("输入无效,请输入男或女。");}}while (true){System.out.println("请您输入您的账户密码:");String passWord = sc.next();System.out.println("请您输入您的确认密码:");String okPassWord = sc.next();// 判断2次密码是否一样。if(okPassWord.equals(passWord)) {account.setPassWord(okPassWord);break;} else {System.out.println("您输入的2次密码不一致,请您确认~~");}}System.out.println("请您输入您的取现额度:");double limit = sc.nextDouble();account.setLimit(limit);String newCard = createCardId();account.setCardId(newCard);// 3、把这个账户对象,存入到账户集合中去accounts.add(account);System.out.println("恭喜您,"+ account.getUserName() + "开户成功,您的卡号是:" + newCard);}// 返回一个8位 数字的卡号,而且这个卡号不能与其他账户的卡号重复private String createCardId(){while (true) {String cardId = "";Random r = new Random();for (int i = 0; i < 8; i++) {int data = r.nextInt(10); // 0 - 9cardId += data;}// 判断cardId中记住的卡号,是否与其他账户的卡号重复了,没有重复,才可以做为一个新卡号返回.Account acc = getAccountByCardId(cardId);if(acc == null){// 说明cardId没有找到账户对象,因此cardId没有与其他账户的卡号重复,可以返回它做为一个新卡号return cardId;}}}// 根据卡号查询账户对象返回 accounts = [c1,c2,c3。]private Account getAccountByCardId(String cardId){// 遍历全部的账户对象for (int i = 0; i < accounts.size(); i++) {Account acc = accounts.get(i);// 判断这个账户对象acc 中的卡号是否是我们要找的卡号if(acc.getCardId().equals(cardId)){return acc;}}return null; // 查无此账户,这个卡号不存在的}
}
接下来,我们会完成这个项目的另一个核心功能:用户登录及登录后的转账等等功能!
相关文章:
java基础练习缺少项目?看这篇文章就够了(上)!
公众号:全干开发 。 专注分享简洁但高质量的动图技术文章! 项目概述 本教程适合刚学习完java基础语法的同学,涉及if语句、循环语句、类的封装、集合等基础概念,使用大量gif图帮助读者演示代码操作、效果等,是一个非常…...
鸿蒙为什么使用typescript 作为开发语言 而不是 flutter 或者 kotlin
猜想如下 dev studio 是基于 idea 二次开发的 ,使用kotlin 应该是更合理 变成 jetbrain 全家桶, 但是 现在android 开发也是kotlin 是不是为了做分割 ,所以不使用kotlin flutter 是谷歌的 安卓也是谷歌的 所以不采用 typescript 是微软的…...
Flutter NestedScrollView 、SliverAppBar全解析,悬浮菜单的应用
在我们开发过程中经常会使用到悬浮菜单的使用,当我们滑动到指定位置后,菜单会自动悬浮。 实现效果如下(左为滑动前、右为滑动后): 上述便是通过NestedScrollView 、SliverAppBar实现的效果,通过两个控件我…...
Mongodb 副本集名称重命名
副本集重命名 要重命名副本集,您必须关闭副本集的所有成员,然后使用新的副本集名称配置每个成员的数据库。 此过程需要停机。 先决条件 确保您的副本集未分片。重命名过程仅适用于未分片的副本集。 在重命名副本集之前,请 对 MongoDB 部…...
C#WPF属性触发器实例
本文讲解C#WPF属性触发器的实例 在属性触发器中,当一个属性发生更改时,它将立即或动画更改另一个属性 实例 <Windowx:Class="TriggerDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://sch…...
Kotlin 核心语法,为什么选择Kotlin ?
Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发。与Java相比,Kotlin的语法更简洁、更具表达性,而且提供了更多的特性。 Kotlin是使用Java开发者的思维被创建的,Intellij作为它主要的开发IDE。对于 Android开发者&#…...
SpringCloud微服务:Nacos的集群、负载均衡、环境隔离
目录 集群 在user-service的yml文件配置集群 启动服务 负载均衡 order-service配置集群 设置负载均衡 当本地集群的服务挂掉时 访问权重 环境隔离 1、Nacos服务分级存储模型 一级是服务,例如userservice 二级是集群,例如杭州或上海 …...
Selenium+Python做web端自动化测试框架实战
最近受到万点暴击,由于公司业务出现问题,工作任务没那么繁重,有时间摸索seleniumpython自动化测试,结合网上查到的资料自己编写出适合web自动化测试的框架,由于本人也是刚刚开始学习python,这套自动化框架目…...
Linux:安装MySQL服务(非docker方式)
1、下载安装包 下载MySQL安装包,需要Oracle官网的账号 下面是网友提供的账号及密码,亲测有效。 账户:3028064308qq.com 我用的这个,可以登陆 密码:OraclePassword123!Oracle Account: 602205528qq.com Oracle Pass…...
C++实现有理数类 四则运算和输入输出
面试 C 程序员,什么样的问题是好问题? - 知乎 https://www.cnblogs.com/bwjblogs/p/12982908.html...
小鸟飞呀飞
欢迎来到程序小院 小鸟飞呀飞 玩法:鼠标控制小鸟飞翔的方向,点击鼠标左键上升,不要让小鸟掉落,从管道中经过,快去飞呀飞哦^^。开始游戏https://www.ormcc.com/play/gameStart/204 html <canvas width"288&quo…...
Unity 场景烘培 ——unity Post-Processing后处理1(四)
提示:文章有错误的地方,还望诸位大神不吝指教! 文章目录 前言一、Post-Processing是什么?二、安装使用Post-Processing1.安装Post-Processing2.使用Post-Processing(1).添加Post-process Volume(…...
Burpsuite抓HTTPS证书导入问题
Burpsuite证书导出有两种方法: 第一种方法 1、开启代理后直接在浏览器中输入burp下载CA证书 2、在中间证书颁发机构中导入刚导出的证书 3、导入完成后再把这个证书选择导出,另存为cer格式的文件 4、在受信任的根证书颁发机构中导入刚保存的cer格式证书…...
python保存文件到zip压缩包中
这里我们使用zipfile这个库进行操作,保存压缩文件相对简单,只需要指定文件名即可,不需要读取那个文件: with zipfile.ZipFile("zip文件路径", mode, zipfile.ZIP_DEFLATED) as z:z.write("压缩源文件路径", …...
java发送媒体类型为multipart/form-data的请求
文章目录 public static String sendMultipartFormDataPostRequest(String urlString, String data) throws IOException {String fullUrl urlString "?" data;log.info("完整请求路径为{}", fullUrl);URL url new URL(fullUrl);HttpURLConnection co…...
自定义类使用ArrayList中的remove
Java中ArrayList对基础类型和字符串类型的删除操作,直接用remove方法即可。但是对于自定义的类来说,用remove方法删除不了,因为没有办法确定是否是要删除的对象。 ArrayList中remove源码是: public boolean remove(Object o) {if…...
前端面试考核点【更持续新中】
文章目录 HTMLcssjsVueReactTypeScript移动端&小程序编译/打包/构建npmnodejs微前端网络安全浏览器性能OKR工程化、标准化 HTML Script放在body中间会阻塞吗?defer与async的区别?https://blog.csdn.net/qq_41887214/article/details/124909219 DOM和…...
linux-docker安装
TOC 一,Docker简介 百科说:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制&…...
如何用html css js 画出曲线 或者斜线;
效果图 解题思路 将图片全部定位至中心点,然后x轴就变动translateX ,y轴同理; 这里有两个问题 浏览器: 以左上角为原点0,0 越往下y越大 数学坐标系:以中心点为原点0,0 越往下y越小࿱…...
【错误记录】Uncaught TypeError: m.nodeName.toLowerCase is not a function
描述:在控制台输出上述错误~ 原因:在页面中,使用jQuery 开发时,命名不能和jQuery一起方法属性冲突,比如这里的nodeName,这里换一个不冲突的名字,就解决问题了。...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
