当前位置: 首页 > news >正文

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基础练习缺少项目?看这篇文章就够了(上)!

公众号&#xff1a;全干开发 。 专注分享简洁但高质量的动图技术文章&#xff01; 项目概述 本教程适合刚学习完java基础语法的同学&#xff0c;涉及if语句、循环语句、类的封装、集合等基础概念&#xff0c;使用大量gif图帮助读者演示代码操作、效果等&#xff0c;是一个非常…...

鸿蒙为什么使用typescript 作为开发语言 而不是 flutter 或者 kotlin

猜想如下 dev studio 是基于 idea 二次开发的 &#xff0c;使用kotlin 应该是更合理 变成 jetbrain 全家桶&#xff0c; 但是 现在android 开发也是kotlin 是不是为了做分割 &#xff0c;所以不使用kotlin flutter 是谷歌的 安卓也是谷歌的 所以不采用 typescript 是微软的…...

Flutter NestedScrollView 、SliverAppBar全解析,悬浮菜单的应用

在我们开发过程中经常会使用到悬浮菜单的使用&#xff0c;当我们滑动到指定位置后&#xff0c;菜单会自动悬浮。 实现效果如下&#xff08;左为滑动前、右为滑动后&#xff09;&#xff1a; 上述便是通过NestedScrollView 、SliverAppBar实现的效果&#xff0c;通过两个控件我…...

Mongodb 副本集名称重命名

副本集重命名 要重命名副本集&#xff0c;您必须关闭副本集的所有成员&#xff0c;然后使用新的副本集名称配置每个成员的数据库。 此过程需要停机。 先决条件 确保您的副本集未分片。重命名过程仅适用于未分片的副本集。 在重命名副本集之前&#xff0c;请 对 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 的新的编程语言&#xff0c;由 JetBrains 开发。与Java相比&#xff0c;Kotlin的语法更简洁、更具表达性&#xff0c;而且提供了更多的特性。 Kotlin是使用Java开发者的思维被创建的&#xff0c;Intellij作为它主要的开发IDE。对于 Android开发者&#…...

SpringCloud微服务:Nacos的集群、负载均衡、环境隔离

目录 集群 在user-service的yml文件配置集群 启动服务 负载均衡 order-service配置集群 设置负载均衡 当本地集群的服务挂掉时 访问权重 环境隔离 1、Nacos服务分级存储模型 一级是服务&#xff0c;例如userservice 二级是集群&#xff0c;例如杭州或上海 …...

Selenium+Python做web端自动化测试框架实战

最近受到万点暴击&#xff0c;由于公司业务出现问题&#xff0c;工作任务没那么繁重&#xff0c;有时间摸索seleniumpython自动化测试&#xff0c;结合网上查到的资料自己编写出适合web自动化测试的框架&#xff0c;由于本人也是刚刚开始学习python&#xff0c;这套自动化框架目…...

Linux:安装MySQL服务(非docker方式)

1、下载安装包 下载MySQL安装包&#xff0c;需要Oracle官网的账号 下面是网友提供的账号及密码&#xff0c;亲测有效。 账户&#xff1a;3028064308qq.com 我用的这个&#xff0c;可以登陆 密码&#xff1a;OraclePassword123!Oracle Account: 602205528qq.com Oracle Pass…...

C++实现有理数类 四则运算和输入输出

面试 C 程序员&#xff0c;什么样的问题是好问题&#xff1f; - 知乎 https://www.cnblogs.com/bwjblogs/p/12982908.html...

小鸟飞呀飞

欢迎来到程序小院 小鸟飞呀飞 玩法&#xff1a;鼠标控制小鸟飞翔的方向&#xff0c;点击鼠标左键上升&#xff0c;不要让小鸟掉落&#xff0c;从管道中经过&#xff0c;快去飞呀飞哦^^。开始游戏https://www.ormcc.com/play/gameStart/204 html <canvas width"288&quo…...

Unity 场景烘培 ——unity Post-Processing后处理1(四)

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、Post-Processing是什么&#xff1f;二、安装使用Post-Processing1.安装Post-Processing2.使用Post-Processing&#xff08;1&#xff09;.添加Post-process Volume&#xff08…...

Burpsuite抓HTTPS证书导入问题

Burpsuite证书导出有两种方法&#xff1a; 第一种方法 1、开启代理后直接在浏览器中输入burp下载CA证书 2、在中间证书颁发机构中导入刚导出的证书 3、导入完成后再把这个证书选择导出&#xff0c;另存为cer格式的文件 4、在受信任的根证书颁发机构中导入刚保存的cer格式证书…...

python保存文件到zip压缩包中

这里我们使用zipfile这个库进行操作&#xff0c;保存压缩文件相对简单&#xff0c;只需要指定文件名即可&#xff0c;不需要读取那个文件&#xff1a; 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对基础类型和字符串类型的删除操作&#xff0c;直接用remove方法即可。但是对于自定义的类来说&#xff0c;用remove方法删除不了&#xff0c;因为没有办法确定是否是要删除的对象。 ArrayList中remove源码是&#xff1a; public boolean remove(Object o) {if…...

前端面试考核点【更持续新中】

文章目录 HTMLcssjsVueReactTypeScript移动端&小程序编译/打包/构建npmnodejs微前端网络安全浏览器性能OKR工程化、标准化 HTML Script放在body中间会阻塞吗&#xff1f;defer与async的区别&#xff1f;https://blog.csdn.net/qq_41887214/article/details/124909219 DOM和…...

linux-docker安装

​TOC 一&#xff0c;Docker简介 百科说&#xff1a;Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化&#xff0c;容器是完全使用沙箱机制&…...

如何用html css js 画出曲线 或者斜线;

效果图 解题思路 将图片全部定位至中心点&#xff0c;然后x轴就变动translateX &#xff0c;y轴同理&#xff1b; 这里有两个问题 浏览器&#xff1a; 以左上角为原点0&#xff0c;0 越往下y越大 数学坐标系&#xff1a;以中心点为原点0&#xff0c;0 越往下y越小&#xff1…...

【错误记录】Uncaught TypeError: m.nodeName.toLowerCase is not a function

描述&#xff1a;在控制台输出上述错误~ 原因&#xff1a;在页面中&#xff0c;使用jQuery 开发时&#xff0c;命名不能和jQuery一起方法属性冲突&#xff0c;比如这里的nodeName&#xff0c;这里换一个不冲突的名字&#xff0c;就解决问题了。...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...