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

商城进货记录交易-课后程序(JAVA基础案例教程-黑马程序员编著-第七章-课后作业)

【实验7-2】商城进货记录交易

【任务介绍】

  1.任务描述

每个商城都需要进货,而这些进货记录整理起来很不方便,本案例要求编写一个商城进货记录交易的程序,使用字节流将商场的进货信息记录在本地的csv文件中。程序具体要求如下:

当用户输入商品编号时,后台会根据商品编号查询到相应商品信息,并打印商品信息。接着让用户输入需要进货的商品数量,程序将原有的库存数量与输入的数量相加作为商品最新的库存数量,并将商品进货的记录保存至本地的csv文件中。在csv文件中,每条记录包含商品编号、商品名称、购买数量、单价、总价、联系人等数据,每条记录的数据之间直接用英文逗号或空格分隔,每条记录之间由换行符分隔。文件命名格式为“进货记录”加上当天日期加上“.csv”后缀,如进货记录“20210611.csv”。保存文件时,需要判断本地是否存在当天的数据,如果存在则追加,不存在则新建。

  2.运行结果

任务运行结果如图7-1所示。

图7-1 运行结果

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

    

 

【实现思路】

  1. 为了方便保存商品的相关信息,可以将商品信息封装为一个实体类。商品进货过程中可能会打印商品相关信息,所以需要对该实体类的toString()方法进行重写,使其能更清晰地显示商品信息,商品每次进货后要修改库存数量,需要在实体类中编写一个操作库存数量的方法。
  2. 对于一个超市,首先会有很多商品,商品需要不断进货。这里我们需要创建一个集合用于模拟超市仓库,然后向集合中添加有具体信息的商品对象,这样一个超市就有了商品。
  3. 管理员进货是通过在控制台键盘输入商品编号和购买数量的方式进行的,如果商品编号正确,且购买数量也正常,则商品进货成功,并将此商品的进货信息保存到csv文件中,同时要将库存数量增加。
  4. 查询商品信息时,可以通过Scanner类的nextInt()方法从控制台获取商品编号,之后根据这个编号到库存中查询此商品的信息,如果查到了商品的信息,从控制台获取进货的数量之后,将此商品的所有信息进行封装。
  5. 将商品的销售信息写入到csv文件之前,需先拼凑好csv文件名,再判断本地是否已存在此文件,这里可通过输入流尝试获取此文件的字节流,如果获取成功,则证明这个文件已存在,那么就通过输出流向文件末尾追加销售信息,如果获取失败,即异常,说明之前并没有生成当日的销售信息,则需要新建此文件。
  6. 将封装的信息写入csv文件中时,csv格式的文件以纯文本形式存储表格数据,写入文件时可以用图7-1的格式写入,当此类文件用Excel格式打开的时候,展现信息如图7-2所示。
  7. 在拼凑csv文件名时,需要获取当日的日期。这里可以通过以下代码来获取并拼凑csv文件名:

DateFormat format = new SimpleDateFormat("yyyyMMdd");// 定义日期格式

String name = "进货记录" + format.format(date) + ".csv";// 拼接文件名

【实现代码】

(1)将商品信息封装成一个实体类Good,具体如文件7-1所示。

文件7-1 Good.java

  1. package chapter0702;
  2. public class Good {
  3.     int id;
  4.     String name;     //商品的价格
  5.     double price;   //商品的单价
  6.     int number;      //进货的数量
  7.     double money;   //总价
  8.     String people;  //审批人
  9.     public Good(int id, String name, double price, int number, double
  10.             money, String people) {
  11.         this.id = id;
  12.         this.name = name;
  13.         this.price = price;
  14.         this.number = number;
  15.         this.money = money;
  16.         this.people = people;
  17.     }
  18.     @Override
  19.     public String toString() {
  20.         String message="进货记录编号:"+id+"\n商品名称:"+name+"" +
  21.                 "\n联系人:"+people+"\n单价:"+price+"\n库存数量:"+number+"\n";
  22.         return message;
  23.     }
  24.     public void setNumber(int number) {
  25.         this.number=number;
  26.     }
  27. }

在文件7-1中,第3~8行代码定义了用于标识商品的信息各种字段,,第9~17行代码定义了一个有参的构造方法,用于对象的创建和初始化,在第18~23行,重写了toString()方法,用于返回商品的详细信息。第24~26行的代码定义了一个setNumber()的方法,用于修改商品的库存量。

(2)定义RecordGoodOrder类来记录和操作商品信息,具体如文件7-2所示。

文件7-2 RecordGoodOrder.java

  1. package chapter0702;
  2. import java.util.ArrayList;
  3. import java.util.Scanner;
  4. public class RecordGoodOrder {
  5.     //创建商品库存
  6.     static ArrayList<Good> goodsList=new ArrayList<Good>();
  7.     public static void main(String[] args) {
  8.         init();  //初始化商品库存
  9.         //将书架上所以商品信息打印出来
  10.         for (int i = 0; i < goodsList.size(); i++) {
  11.             System.out.println(goodsList.get(i));
  12.         }
  13.         while(true) {
  14.             //获取控制台输入的信息
  15.             Scanner scan=new Scanner(System.in);
  16.             System.out.println("请输入商品编号");
  17.             int goodId=scan.nextInt();
  18.             Good stockGood=getGoodsById(goodId);
  19.             if (stockGood != null) {// 判断是否存在此商品
  20.                 System.out.println("当前商品库存信息" + stockGood);
  21.                 System.out.print("请输入进货数量:");
  22.                 int goodNumber = scan.nextInt();
  23.                 // 将输入信息封装成Good对象
  24.                 Good good = new Good(stockGood.id, stockGood.name,
  25.                         stockGood.price, goodNumber, stockGood.price
  26.                         * goodNumber, stockGood.people);
  27.                 FileUtil.saveGoods(good);// 将本条数据保存至本地文件
  28.                 // 修改库存
  29.                 stockGood.setNumber(stockGood.number + goodNumber);
  30.             } else {
  31.                 System.out.println("商品编号输入错误!");
  32.             }
  33.         }
  34.     }
  35.     /*
  36.      * 初始化商品库存的信息 将商品存入库存
  37.      */
  38.     private static void init() {
  39.         Good good1=new Good(1001,"百事可乐",4.5,100,450,"张三");
  40.         Good good2=new Good(1002,"可口可乐",4,100,400,"李四");
  41.         Good good3=new Good(1003,"百事雪碧",3.8,100,380,"张三");
  42.         goodsList.add(good1);
  43.         goodsList.add(good2);
  44.         goodsList.add(good3);
  45.     }
  46.     /*
  47.      * 根据输入的商品编号查找商品信息,循环遍历库存中商品信息,找到商品编号相等的取出
  48.      */
  49.     private static Good getGoodsById(int goodId) {
  50.         for (int i = 0; i < goodsList.size(); i++) {
  51.             Good thisGood=goodsList.get(i);
  52.             if (goodId==thisGood.id) {
  53.                 return thisGood;
  54.             }
  55.         }
  56.         return null;
  57.     }
  58. }

在文件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

  1. package chapter0702;
  2. import java.io.BufferedOutputStream;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.text.DateFormat;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. /**
  12.  * 工具类
  13.  */
  14. public class FileUtil {
  15.     public static final String SEPARATE_FIELD = ",";// 字段分隔 英文逗号
  16.     public static final String SEPARATE_LINE = "\r\n";// 行分隔
  17.     /**
  18.      * 保存商品信息
  19.      */
  20.     public static void saveGoods(Good good) {
  21.         // 判断本地是否存在此文件
  22.         Date date = new Date();
  23.         // 定义日期格式
  24.         DateFormat format = new SimpleDateFormat("yyyyMMdd");
  25.         // 拼接文件名
  26.         String name = "进货记录" + format.format(date) + ".csv";
  27.         InputStream in = null;
  28.         try {
  29.             in = new FileInputStream(name);// 判断本地是否存在此文件
  30.             if (in != null) {
  31.                 in.close();// 关闭输入流
  32.                 // 可获取输入流,则存在文件,采取修改文件方式
  33.                 createFile(name, true, good);
  34.             }
  35.         } catch (FileNotFoundException e) {
  36.             // 输入流获取失败,则不存在文件,采取新建新文件方式
  37.             createFile(name, false, good);
  38.         } catch (IOException e) {
  39.             e.printStackTrace();
  40.         }
  41.     }
  42.     /**
  43.      * 将进货记录的信息保存到本地,可通过label标识来判断是修改文件还是新建文件
  44.      * @param name  文件名
  45.      * @param label 文件已存在的标识 true:已存在则修改; false:不存在则新建
  46.      * @param good  商品信息
  47.      */
  48.     public static void createFile(String name,boolean label,Good good) {
  49.         BufferedOutputStream out = null;
  50.         StringBuffer sbf = new StringBuffer();// 拼接内容
  51.         try {
  52.             if (label) {// 当已存在当天的文件,则在文件内容后追加
  53.             // 创建输出流,用于追加文件
  54.              out = new BufferedOutputStream(new FileOutputStream(name, true));
  55.             } else {// 不存在当天文件,则新建文件
  56.                 // 创建输出流,用于保存文件
  57.                out = new BufferedOutputStream(new FileOutputStream(name));
  58.         String[] fieldSort = new String[] { "商品编号", "商品名称", "购买数量",
  59.                         "单价", "总价", "联系人" };// 创建表头
  60.                 for (String fieldKye : fieldSort) {
  61.                     // 新建时,将表头存入本地文件
  62.                     sbf.append(fieldKye).append(SEPARATE_FIELD);
  63.                 }
  64.            }
  65.                 sbf.append(SEPARATE_LINE);// 追加换行符号
  66.                 sbf.append(good.id).append(SEPARATE_FIELD);
  67.                 sbf.append(good.name).append(SEPARATE_FIELD);
  68.                 sbf.append(good.number).append(SEPARATE_FIELD);
  69.                 sbf.append((double) good.price).append(SEPARATE_FIELD);
  70.                 sbf.append((double) good.money).append(SEPARATE_FIELD);
  71.                 sbf.append(good.people).append(SEPARATE_FIELD);
  72.                 String str = sbf.toString();
  73.                 byte[] b = str.getBytes();
  74.                 for (int i = 0; i < b.length; i++) {
  75.                     out.write(b[i]);// 将内容写入本地文件
  76.                 }
  77.             } catch (Exception e) {
  78.                 e.printStackTrace();
  79.             } finally {
  80.                 try {
  81.                     if (out != null)
  82.                         out.close();// 关闭输出流
  83.                 } catch (Exception e2) {
  84.                     e2.printStackTrace();
  85.                 }
  86.             }
  87.         }
  88.     }

在文件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.任务描述 每个商城都需要进货&#xff0c;而这些进货记录整理起来很不方便&#xff0c;本案例要求编写一个商城进货记录交易的程序&#xff0c;使用字节流将商场的进货信息记录在本地的csv文件中。程序具体要求如下&#xff1a; …...

【正点原子FPGA连载】第十七章双核AMP实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

1&#xff09;实验平台&#xff1a;正点原子MPSoC开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id692450874670 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第十七章双核AMP…...

内存管理框架---页(一)

文章目录物理内存的模型非一致内存访问--NUMA一致内存访问模型--UMA内存管理架构页页框管理页描述符页描述符字段flags字段详解gfp_mask 标志获得页alloc_pages__get_free_pages获得填充为0的页释放页kmallocvmalloc参考资料你用心写的每一篇文章&#xff0c;可能会带别人和自己…...

华为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 中&#xff0c;JDK 10 开始提供替换&#xff08;得益于 HotSpot 编译器接口&#xff0c;Jav…...

蓝牙标签操作指南

一、APP安装指南 1.APP权限问题 电子标签APP安装之后&#xff0c;会提示一些权限的申请&#xff0c;点击允许。否则某些会影响APP的正常运行。安装后&#xff0c;搜索不到蓝牙标签&#xff0c;可以关闭App&#xff0c;重新打开。 2.手机功能 运行APP时候&#xff0c;需要打开…...

嵌入式 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前端学习:一

编辑器的基础使用 编辑器推荐使用&#xff1a; HBuilderx&#xff08;免费中文&#xff09;&#xff08;建议使用&#xff09; Sublime&#xff08;免费英文&#xff09; Sublime中文设置方法&#xff0c;下载语言插件&#xff1a; 1、进入Sublime后&#xff0c;ShiftCtrlP…...

SpringBoot集成Redis实现分布式会话

在单体应用的时代&#xff0c;Session 会话直接保存在服务器中&#xff0c;实现非常简单&#xff0c;但是随着微服务的流行&#xff0c;现代应用架构基本都是分布式架构&#xff0c;请求随机的分配到后端的多个应用中&#xff0c;此时session就需要共享&#xff0c;而存储在red…...

2023年关于身份安全的4 个预测

如果您身处技术领域&#xff0c;就会知道现在是时候盘点过去的一年&#xff0c;展望未来 365 天将影响业务、创新以及我们工作方式的因素的季节。这不是一门精确的科学&#xff0c;我们也不总是对的。但是推测很有趣&#xff0c;当我们看到其中一些趋势成为现实时会更有趣。本文…...

Linux期末考试应急

Linux期末考试应急 虚拟机添加硬盘、分区、格式化、挂载、卸载 fdisk -l#查看系统现有分区fdisk <指定磁盘>#指定磁盘分区sudo mkfs.ext3 <指定分区>#格式化磁盘###挂载磁盘1.新建一个目录sudo mkdir /mnt/test2.将指定分区挂载到对应目录sudo mount /dev/sdb10 /…...

mars3d对geojson图层分属性设置样式

开发中可能会遇到如下需求&#xff0c;在全省的数据中按某个属性⾼亮展示某市区。此时就需要使⽤分属性样式的api了。⽂档如下。GeoJsonLayer - Mars3D API文档属性是根据⽮量数据的属性进⾏匹配。可以通过 layer.graphics[0]?.attr ⽅式获取。 指导有哪些属性之后先设置…...

三、锁相关知识

文章目录锁的分类可重入锁、不可重入锁乐观锁、悲观锁公平锁、非公平锁互斥锁、共享锁深入synchronized类锁、对象锁synchronized的优化synchronized实现原理synchronized的锁升级重量锁底层ObjectMonitor深入ReentrantLockReentrantLock和synchronized的区别AQS概述加锁流程源…...

C语言数据类型

C 数据类型 在 C 语言中&#xff0c;数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间&#xff0c;以及如何解释存储的位模式。 C 中的类型可分为以下几种&#xff1a; 1 基本类型&#xff1a; 它们是算术类型&#xff0c;…...

华为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有哪些优势&#xff1f;1.性能媲美原生APP 2.使用JavaScript编码&#xff0c;只要学习这一种语言 3.绝大部分代码安卓和IOS都能共用 4.组件式开发&#xff0c;代码重用性很高 5.跟编写网页一般&#xff0c;修改代码后即可自动刷…...

【数据存储】浮点型在内存中的存储

目录 一、存储现象 二、IEEE标准规范 1.存储 2.读取 三、举例验证 1.存储 2.读取 浮点型存储的标准是IEEE&#xff08;电气电子工程师学会&#xff09;754制定的。 一、存储现象 浮点数由于其有小数点的特殊性&#xff0c;有很多浮点数是不能精确存储的&#xff0c;如&#…...

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 初始化窗口看门狗…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

第19节 Node.js Express 框架

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

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架&#xff0c;实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...