商城进货记录交易-课后程序(JAVA基础案例教程-黑马程序员编著-第七章-课后作业)
【实验7-2】商城进货记录交易
【任务介绍】
1.任务描述
每个商城都需要进货,而这些进货记录整理起来很不方便,本案例要求编写一个商城进货记录交易的程序,使用字节流将商场的进货信息记录在本地的csv文件中。程序具体要求如下:
当用户输入商品编号时,后台会根据商品编号查询到相应商品信息,并打印商品信息。接着让用户输入需要进货的商品数量,程序将原有的库存数量与输入的数量相加作为商品最新的库存数量,并将商品进货的记录保存至本地的csv文件中。在csv文件中,每条记录包含商品编号、商品名称、购买数量、单价、总价、联系人等数据,每条记录的数据之间直接用英文逗号或空格分隔,每条记录之间由换行符分隔。文件命名格式为“进货记录”加上当天日期加上“.csv”后缀,如进货记录“20210611.csv”。保存文件时,需要判断本地是否存在当天的数据,如果存在则追加,不存在则新建。
2.运行结果
任务运行结果如图7-1所示。

图7-1 运行结果
运行结束后在本地生成一个“进货记录20210611.csv”文件,用Excel方式打开此文件,如图7-1所示。

【实现思路】
- 为了方便保存商品的相关信息,可以将商品信息封装为一个实体类。商品进货过程中可能会打印商品相关信息,所以需要对该实体类的toString()方法进行重写,使其能更清晰地显示商品信息,商品每次进货后要修改库存数量,需要在实体类中编写一个操作库存数量的方法。
- 对于一个超市,首先会有很多商品,商品需要不断进货。这里我们需要创建一个集合用于模拟超市仓库,然后向集合中添加有具体信息的商品对象,这样一个超市就有了商品。
- 管理员进货是通过在控制台键盘输入商品编号和购买数量的方式进行的,如果商品编号正确,且购买数量也正常,则商品进货成功,并将此商品的进货信息保存到csv文件中,同时要将库存数量增加。
- 查询商品信息时,可以通过Scanner类的nextInt()方法从控制台获取商品编号,之后根据这个编号到库存中查询此商品的信息,如果查到了商品的信息,从控制台获取进货的数量之后,将此商品的所有信息进行封装。
- 将商品的销售信息写入到csv文件之前,需先拼凑好csv文件名,再判断本地是否已存在此文件,这里可通过输入流尝试获取此文件的字节流,如果获取成功,则证明这个文件已存在,那么就通过输出流向文件末尾追加销售信息,如果获取失败,即异常,说明之前并没有生成当日的销售信息,则需要新建此文件。
- 将封装的信息写入csv文件中时,csv格式的文件以纯文本形式存储表格数据,写入文件时可以用图7-1的格式写入,当此类文件用Excel格式打开的时候,展现信息如图7-2所示。
- 在拼凑csv文件名时,需要获取当日的日期。这里可以通过以下代码来获取并拼凑csv文件名:
DateFormat format = new SimpleDateFormat("yyyyMMdd");// 定义日期格式
String name = "进货记录" + format.format(date) + ".csv";// 拼接文件名
【实现代码】
(1)将商品信息封装成一个实体类Good,具体如文件7-1所示。
文件7-1 Good.java
- package chapter0702;
- public class Good {
- int id;
- String name; //商品的价格
- double price; //商品的单价
- int number; //进货的数量
- double money; //总价
- String people; //审批人
- public Good(int id, String name, double price, int number, double
- money, String people) {
- this.id = id;
- this.name = name;
- this.price = price;
- this.number = number;
- this.money = money;
- this.people = people;
- }
- @Override
- public String toString() {
- String message="进货记录编号:"+id+"\n商品名称:"+name+"" +
- "\n联系人:"+people+"\n单价:"+price+"\n库存数量:"+number+"\n";
- return message;
- }
- public void setNumber(int number) {
- this.number=number;
- }
- }
在文件7-1中,第3~8行代码定义了用于标识商品的信息各种字段,,第9~17行代码定义了一个有参的构造方法,用于对象的创建和初始化,在第18~23行,重写了toString()方法,用于返回商品的详细信息。第24~26行的代码定义了一个setNumber()的方法,用于修改商品的库存量。
(2)定义RecordGoodOrder类来记录和操作商品信息,具体如文件7-2所示。
文件7-2 RecordGoodOrder.java
- package chapter0702;
- import java.util.ArrayList;
- import java.util.Scanner;
- public class RecordGoodOrder {
- //创建商品库存
- static ArrayList<Good> goodsList=new ArrayList<Good>();
- public static void main(String[] args) {
- init(); //初始化商品库存
- //将书架上所以商品信息打印出来
- for (int i = 0; i < goodsList.size(); i++) {
- System.out.println(goodsList.get(i));
- }
- while(true) {
- //获取控制台输入的信息
- Scanner scan=new Scanner(System.in);
- System.out.println("请输入商品编号");
- int goodId=scan.nextInt();
- Good stockGood=getGoodsById(goodId);
- if (stockGood != null) {// 判断是否存在此商品
- System.out.println("当前商品库存信息" + stockGood);
- System.out.print("请输入进货数量:");
- int goodNumber = scan.nextInt();
- // 将输入信息封装成Good对象
- Good good = new Good(stockGood.id, stockGood.name,
- stockGood.price, goodNumber, stockGood.price
- * goodNumber, stockGood.people);
- FileUtil.saveGoods(good);// 将本条数据保存至本地文件
- // 修改库存
- stockGood.setNumber(stockGood.number + goodNumber);
- } else {
- System.out.println("商品编号输入错误!");
- }
- }
- }
- /*
- * 初始化商品库存的信息 将商品存入库存
- */
- private static void init() {
- Good good1=new Good(1001,"百事可乐",4.5,100,450,"张三");
- Good good2=new Good(1002,"可口可乐",4,100,400,"李四");
- Good good3=new Good(1003,"百事雪碧",3.8,100,380,"张三");
- goodsList.add(good1);
- goodsList.add(good2);
- goodsList.add(good3);
- }
- /*
- * 根据输入的商品编号查找商品信息,循环遍历库存中商品信息,找到商品编号相等的取出
- */
- private static Good getGoodsById(int goodId) {
- for (int i = 0; i < goodsList.size(); i++) {
- Good thisGood=goodsList.get(i);
- if (goodId==thisGood.id) {
- return thisGood;
- }
- }
- return null;
- }
- }
在文件7-8中,第6行代码创建了ArrayList类型的全局变量作为商品的仓库。第39~46代码,初始化了商品信息,向ArrayList中添加了3种商品的信息,并在第10~12行代码中,通过for循环进行展示。第13~34行代码使用while循环来获取和处理用户输入信息,每次循环先由第16~17行代码,从控制台获取商品编号的数据,再由第49~57行的代码,根据商品编号查询到商品信息,当获得的商品信息不为空时,可从第21~22代码获得购买的数量,可通过24~29的代码,将所有数据封装,再利用第27行代码,调用FileUtil类中的saveGoods()方法,将其保存至本地。最后在第29行代码中调用setNumber()方法,修改库存。
(3)定义工具类FileUtil保存商品信息,具体如文件7-3所示。
文件7-3 FileUtil.java
- package chapter0702;
- import java.io.BufferedOutputStream;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.text.DateFormat;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- /**
- * 工具类
- */
- public class FileUtil {
- public static final String SEPARATE_FIELD = ",";// 字段分隔 英文逗号
- public static final String SEPARATE_LINE = "\r\n";// 行分隔
- /**
- * 保存商品信息
- */
- public static void saveGoods(Good good) {
- // 判断本地是否存在此文件
- Date date = new Date();
- // 定义日期格式
- DateFormat format = new SimpleDateFormat("yyyyMMdd");
- // 拼接文件名
- String name = "进货记录" + format.format(date) + ".csv";
- InputStream in = null;
- try {
- in = new FileInputStream(name);// 判断本地是否存在此文件
- if (in != null) {
- in.close();// 关闭输入流
- // 可获取输入流,则存在文件,采取修改文件方式
- createFile(name, true, good);
- }
- } catch (FileNotFoundException e) {
- // 输入流获取失败,则不存在文件,采取新建新文件方式
- createFile(name, false, good);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 将进货记录的信息保存到本地,可通过label标识来判断是修改文件还是新建文件
- * @param name 文件名
- * @param label 文件已存在的标识 true:已存在则修改; false:不存在则新建
- * @param good 商品信息
- */
- public static void createFile(String name,boolean label,Good good) {
- BufferedOutputStream out = null;
- StringBuffer sbf = new StringBuffer();// 拼接内容
- try {
- if (label) {// 当已存在当天的文件,则在文件内容后追加
- // 创建输出流,用于追加文件
- out = new BufferedOutputStream(new FileOutputStream(name, true));
- } else {// 不存在当天文件,则新建文件
- // 创建输出流,用于保存文件
- out = new BufferedOutputStream(new FileOutputStream(name));
- String[] fieldSort = new String[] { "商品编号", "商品名称", "购买数量",
- "单价", "总价", "联系人" };// 创建表头
- for (String fieldKye : fieldSort) {
- // 新建时,将表头存入本地文件
- sbf.append(fieldKye).append(SEPARATE_FIELD);
- }
- }
- sbf.append(SEPARATE_LINE);// 追加换行符号
- sbf.append(good.id).append(SEPARATE_FIELD);
- sbf.append(good.name).append(SEPARATE_FIELD);
- sbf.append(good.number).append(SEPARATE_FIELD);
- sbf.append((double) good.price).append(SEPARATE_FIELD);
- sbf.append((double) good.money).append(SEPARATE_FIELD);
- sbf.append(good.people).append(SEPARATE_FIELD);
- String str = sbf.toString();
- byte[] b = str.getBytes();
- for (int i = 0; i < b.length; i++) {
- out.write(b[i]);// 将内容写入本地文件
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (out != null)
- out.close();// 关闭输出流
- } catch (Exception e2) {
- e2.printStackTrace();
- }
- }
- }
- }
在文件7-3中,当saveGoods()方法被调用时,获取当前日期并格式化后,拼出了文件名,再通过第29行代码尝试获取此文件的字节输入流。当能够获取输入流时,可通过第30~34行代码,先关闭输入流,再在文件末尾追加信息。当不能获取输入流时则抛出异常,在异常处理中调用第37行代码的createFile()方法,可以通过此方法中的label参数来区分,是新建文件还是在已有文件中追加内容,如果label值是true则追加内容,如果label值是false则新建文件,并写入表头,其中进行追加还是新建操作,由构造函数的append参数来定义。然后利用65~72行代码拼出一行数据,且在每次拼接之前都要加上换行符“\r\n”,每个字段之间通过“,”分隔字段,再利用第73~76行的代码写入文件。最后80~86行代码关闭了输出流。
相关文章:
商城进货记录交易-课后程序(JAVA基础案例教程-黑马程序员编著-第七章-课后作业)
【实验7-2】商城进货记录交易 【任务介绍】 1.任务描述 每个商城都需要进货,而这些进货记录整理起来很不方便,本案例要求编写一个商城进货记录交易的程序,使用字节流将商场的进货信息记录在本地的csv文件中。程序具体要求如下: …...
【正点原子FPGA连载】第十七章双核AMP实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南
1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第十七章双核AMP…...
内存管理框架---页(一)
文章目录物理内存的模型非一致内存访问--NUMA一致内存访问模型--UMA内存管理架构页页框管理页描述符页描述符字段flags字段详解gfp_mask 标志获得页alloc_pages__get_free_pages获得填充为0的页释放页kmallocvmalloc参考资料你用心写的每一篇文章,可能会带别人和自己…...
华为OD机试真题Python实现【流水线】真题+解题思路+代码(20222023)
流水线 题目 一个工厂有m条流水线 来并行完成n个独立的作业 该工厂设置了一个调度系统 在安排作业时,总是优先执行处理时间最短的作业 现给定流水线个数m 需要完成的作业数n 每个作业的处理时间分别为 t1,t2...tn 请你编程计算处理完所有作业的耗时为多少 当n > m时 首先…...
「JVM 编译优化」Graal 编译器
文章目录1. 历史背景2. 构建编译调试环境3. JVMCI 编译器接口4. 代码中间表示5. 代码优化与生成1. 历史背景 Graal 编译器在 JDK 9 以 Jaotc 提前编译工具的形式首次加入到官方的 JDK 中,JDK 10 开始提供替换(得益于 HotSpot 编译器接口,Jav…...
蓝牙标签操作指南
一、APP安装指南 1.APP权限问题 电子标签APP安装之后,会提示一些权限的申请,点击允许。否则某些会影响APP的正常运行。安装后,搜索不到蓝牙标签,可以关闭App,重新打开。 2.手机功能 运行APP时候,需要打开…...
嵌入式 Linux Shell编程
目录 1、shell脚本 2、执行shell脚本 3、shell脚本编写 3.1 shell变量 3.2 标准变量或环境变量 3.4 变量赋值有五种格式 3.5 运算符和表达式 关系运算符 布尔运算符 3.6 Test命令用法 1、判断表达式 2、判断字符串 3.判断整数 4、判断文件 3.7 数组 1、数组定义…...
Web前端学习:一
编辑器的基础使用 编辑器推荐使用: HBuilderx(免费中文)(建议使用) Sublime(免费英文) Sublime中文设置方法,下载语言插件: 1、进入Sublime后,ShiftCtrlP…...
SpringBoot集成Redis实现分布式会话
在单体应用的时代,Session 会话直接保存在服务器中,实现非常简单,但是随着微服务的流行,现代应用架构基本都是分布式架构,请求随机的分配到后端的多个应用中,此时session就需要共享,而存储在red…...
2023年关于身份安全的4 个预测
如果您身处技术领域,就会知道现在是时候盘点过去的一年,展望未来 365 天将影响业务、创新以及我们工作方式的因素的季节。这不是一门精确的科学,我们也不总是对的。但是推测很有趣,当我们看到其中一些趋势成为现实时会更有趣。本文…...
Linux期末考试应急
Linux期末考试应急 虚拟机添加硬盘、分区、格式化、挂载、卸载 fdisk -l#查看系统现有分区fdisk <指定磁盘>#指定磁盘分区sudo mkfs.ext3 <指定分区>#格式化磁盘###挂载磁盘1.新建一个目录sudo mkdir /mnt/test2.将指定分区挂载到对应目录sudo mount /dev/sdb10 /…...
mars3d对geojson图层分属性设置样式
开发中可能会遇到如下需求,在全省的数据中按某个属性⾼亮展示某市区。此时就需要使⽤分属性样式的api了。⽂档如下。GeoJsonLayer - Mars3D API文档属性是根据⽮量数据的属性进⾏匹配。可以通过 layer.graphics[0]?.attr ⽅式获取。 指导有哪些属性之后先设置…...
三、锁相关知识
文章目录锁的分类可重入锁、不可重入锁乐观锁、悲观锁公平锁、非公平锁互斥锁、共享锁深入synchronized类锁、对象锁synchronized的优化synchronized实现原理synchronized的锁升级重量锁底层ObjectMonitor深入ReentrantLockReentrantLock和synchronized的区别AQS概述加锁流程源…...
C语言数据类型
C 数据类型 在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。 C 中的类型可分为以下几种: 1 基本类型: 它们是算术类型,…...
华为OD机试真题Python实现【水仙花数】真题+解题思路+代码(20222023)
水仙花数 题目 所谓的水仙花数是指一个n位的正整数其各位数字的n次方的和等于该数本身, 例如153 = 1^3 + 5^3 + 3^3,153是一个三位数 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇总 输入 第一行输入一个整数N, 表示 N 位的正整数 N 在3…...
【华为OD机试模拟题】用 C++ 实现 - 非严格递增连续数字序列(2023.Q1)
最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...
RN面试题
RN面试题1.React Native相对于原生的ios和Android有哪些优势?1.性能媲美原生APP 2.使用JavaScript编码,只要学习这一种语言 3.绝大部分代码安卓和IOS都能共用 4.组件式开发,代码重用性很高 5.跟编写网页一般,修改代码后即可自动刷…...
【数据存储】浮点型在内存中的存储
目录 一、存储现象 二、IEEE标准规范 1.存储 2.读取 三、举例验证 1.存储 2.读取 浮点型存储的标准是IEEE(电气电子工程师学会)754制定的。 一、存储现象 浮点数由于其有小数点的特殊性,有很多浮点数是不能精确存储的,如&#…...
Servlet笔记(8):异常处理
1、错误页面配置 web.xml <!-- servlet 定义 --> <servlet><servlet-name>ErrorHandler</servlet-name><servlet-class>ErrorHandler</servlet-class> </servlet> <!-- servlet 映射 --> <servlet-mapping><servle…...
stm32f407探索者开发板(二十一)——窗口看门狗
文章目录一、窗口看门狗概述1.1 看门狗框图1.2 窗口看门狗工作过程总结1.3 超时时间1.4 为什么需要窗口看门狗1.5 其他注意事项二、常用寄存器和库函数2.1 控制寄存器WWDG_ CR2.2 配置寄存器WWDG_ CFR2.3 状态寄存器WWDG_SR三、手写窗口看门狗3.1 配置过程3.2 初始化窗口看门狗…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
