【前端学java】java基础练习缺少项目?看这篇文章就够了!(17)

简介: 【8月更文挑战第11天】java基础练习缺少项目?看这篇文章就够了!

项目概述

本教程适合刚学习完java基础语法的同学,涉及if语句、循环语句、类的封装、集合等基础概念,使用大量gif图帮助读者演示代码操作、效果等,是一个非常不错的巩固练习教程!不涉及任何java框架等内容,可以放心食用!

本教程将使用控制台模拟一个ATM取款机!

基础需求演示

ATM机主要有用户开户用户登录(登录后可以转账等)功能,我们简单演示一下用户开户功能!
GIF 2023-11-2 10-21-59.gif

系统架构

根据我们的需求,我们可以知道,我们的这个程序应该主要包含两个类

  • 账户类Account:包含卡号、姓名、性别、密码、余额、额度等属性
  • ATM类:代表ATM系统,负责提供业务需求,具备欢迎页、转账、开通账户等功能

    项目搭建

    创建项目

    打开编译器,创建名为Project_ATM的项目
    GIF 2023-10-31 18-37-10.gif

    创建Account类

    Account类用来表示账户信息,包含卡号、姓名、性别、密码、余额、额度等属性,我们创建这个类,并完善一些基本属性
    GIF 2023-11-1 10-20-20.gif
    Acount的基本属性创建完毕后,我们需要给这些属性创建get和set方法,用来方便快捷的更改读取这些数值。
    我们使用IDEA的快捷操作:
    光标放在Account类内部,右键点击【Generate】,点击【Getter and Setter】,点住ctrl键不放,选中Acoount的所有属性,点击【ok】即可
    GIF 2023-11-1 10-32-35.gif
    生成的代码如下:
    ```java
    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
![GIF 2023-11-1 10-43-14.gif](https://cdn.nlark.com/yuque/0/2023/gif/21865277/1698807440533-d8d2c46c-1995-4ae7-8bbc-0bd3e89a4bb7.gif#averageHue=%23323436&clientId=u71240843-81ee-4&from=drop&id=u062c9579&originHeight=722&originWidth=1396&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=532487&status=done&style=none&taskId=u1db48f51-8053-40c9-9912-61b75576773&title=)
```java
import java.util.ArrayList;

public class ATM {
    private ArrayList<Account> accounts = new ArrayList<>();
}

我们的欢迎页是在控制台显示的,长下面这个样子
image.png
我们用代码实现一下这个逻辑

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类验证下:
GIF 2023-11-1 17-35-26.gif

public class Text {
   
   
    public static void main(String[] args) {
   
   
        // 创建atm类,代表一个ATM系统
        ATM atm = new ATM();
        //启动ATM系统
        atm.start();
    }
}

我们执行这个函数试试效果GIF 2023-11-1 17-40-36.gif
不错,很完美!

开户功能完善

功能简介

开户功能就是新增一个账户,也就是向系统的账户集合添加一个账户对象,这个账户对象应该包含用户输入的姓名、性别、密码及每次取现的额度信息;同时,还有一个系统生成的随机卡号(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语句中,我们需要终止循环
GIF 2023-11-1 20-18-18.gif
最后,我们完善下其他方法

// 用户开户操作
    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()方法
image.png
然后再Tset类中运行程序试试看GIF 2023-11-1 20-20-51.gif
丝滑流畅!

生长卡号信息

卡号是一个8位的数字,且和已有卡号不能重复,它的创建分为以下几个步骤
定义一个string类型的变量记住8位数字作为一个卡号

String cardId = "";

使用循环,循环8次,每次产生一个随机数给cardId连接起来

Random r = new Random();
for (int i = ; i < 8; i++) {
   
   
  int data = r.nextInt( bound: 10); // 0 - 9
  cardId += 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 - 9
                cardId += 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);
  }

GIF 2023-11-2 10-21-59.gif

结语

至此,我们的开户功能就完成了!下面是开户功能的完整代码!

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 - 9
                cardId += 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; // 查无此账户,这个卡号不存在的
    }
}

接下来,我们会完成这个项目的另一个核心功能:用户登录及登录后的转账等等功能!

相关文章
|
5天前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
55 23
|
9天前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
105 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
22天前
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
60 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
1月前
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
64 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
1月前
|
JavaScript NoSQL Java
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
186 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
|
1月前
|
网络协议 Java Shell
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
72 7
|
1月前
|
SQL JavaScript 安全
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
86 11
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
|
1月前
|
前端开发 JavaScript Java
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
131 13
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
|
1月前
|
人工智能 JavaScript 关系型数据库
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
99 14
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
|
12天前
|
Java 调度
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
81 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码

热门文章

最新文章