商城进货记录交易-课后程序(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 初始化窗口看门狗…...
Intel集成显卡加速PyTorch:从环境搭建到模型训练实战指南
1. 为什么选择Intel集成显卡加速PyTorch? 很多朋友刚接触深度学习时,第一反应都是"得买块N卡"。但你可能不知道,手头的Intel集成显卡也能跑PyTorch,而且效果还不错。我去年给团队配开发机时,就专门测试过Int…...
Python异步爬虫实战:如何避免aiohttp的ServerDisconnectedError(附完整代码)
Python异步爬虫实战:深度解决aiohttp的ServerDisconnectedError问题 最近在帮朋友优化一个电商价格监控项目时,遇到了令人头疼的ServerDisconnectedError。每当爬取量超过5000条商品数据时,程序就会随机崩溃,控制台满是红色错误日…...
避坑指南:WFDB读取ECG数据时,.hea文件真的‘几乎没用’吗?
避坑指南:WFDB读取ECG数据时,.hea文件真的‘几乎没用’吗? 在生物信号处理领域,WFDB(Waveform Database)格式是存储心电图(ECG)数据的黄金标准。许多开发者习惯性地认为.hea头文件只…...
AI编程革命:重塑程序员未来(一)
AI编程时代到来AI不会让程序员消失,但会深刻重塑这个职业。当代码生成变得轻而易举,程序员 的角色将从“代码编写者”升级为“问题解决者”与“架构设计师”。未来的核心竞争力,在于 理解复杂业务、设计系统逻辑,并用人类独有的创…...
对在aarch64 Linux环境编译安装的CinderX补充测试
前文最后说,CinderX报错不能用,这不对,我在其github存储库上提了这个issue,alexmalyshev回复 I think that’s actually just a warning that you’re getting but things should be working after that?Right, this is just a l…...
AI 焦虑别乱投!3 个问题秒懂要不要养「虾」
作者 | 张辉清 责编 | 梦依丹出品 | 程序人生(ID:coder_life)当下 AI 热度居高不下,企业该如何抉择?是大举投入布局,还是保持观望?我们借以下三个问题来展开思考。AI 当下处在什么阶段…...
AutoGLM沉思版 vs OpenAI DeepResearch:免费国产AI Agent能否替代200美元/月的服务?
AutoGLM沉思版与OpenAI DeepResearch深度对比:企业级AI研究工具如何选择? 当企业研发团队需要处理海量文献综述时,当投资机构需要快速生成行业分析报告时,技术决策者往往面临一个关键选择:是选择国际知名但价格高昂的O…...
SecGPT-14B完整指南:从镜像拉取、服务启动、参数调优到故障排查
SecGPT-14B完整指南:从镜像拉取、服务启动、参数调优到故障排查 1. SecGPT-14B简介 SecGPT-14B是一款专注于网络安全领域的文本生成模型,基于Qwen2ForCausalLM架构开发,拥有140亿参数规模。该模型专为安全专业人员设计,能够提供…...
基于支持向量机SVM预测飞机延误率的Python项目
数据挖掘项目-基于支持向量机svm预测飞机延误率(python) 关键技术:支持向量机SVMKNN 包含内容:数据集代码文档 (字数8436) 引言 飞机延误是航空运输中常见的问题。航班延误不仅影响乘客的出行体验&#x…...
北海本地人私藏的美食哪家好
在北海这座滨海城市,海鲜饮食的日常逻辑始终围绕着“活鲜”二字展开。本地食客习惯于清晨去渔港挑海鲜,或选择街边老店加工,追求的是食材本身的呼吸感与原味。而近年来,随着游客流量增长,海鲜餐饮的消费场景发生着结构…...
