当前位置: 首页 > 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 初始化窗口看门狗…...

C++ 模板

1. 泛型编程实现一个通用的交换函数&#xff0c;使用函数重载虽然可以实现&#xff0c;但是有以 下几个不好的地方&#xff1a;1. 重载的函数仅仅是类型不同&#xff0c;代码复用率比较低&#xff0c;只要有新类型出现时&#xff0c;就需要用户自己增加对应的函数2. 代码的可维…...

C++中的友元及运算符重载

友元 意义 程序中&#xff0c;有些私有属性也想让类外特殊的一些函数或者类进行访问&#xff0c;就要用到友元技术 关键字 friend 友元的三种实现 全局函数做友元 class Room{friend void test(Person &p);//friend class test;public:string phone_number;private:string…...

五、运行时数据区内部结构、JVM中的线程

内存是非常重要的系统资源&#xff0c;是硬盘和cpu的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程种内存申请、分配‘、管理的策略&#xff0c;保证了JVM的高效稳定运行&#xff0c;不同的JVM对于内存的划分方式和管理机制…...

Codeforces Round #848 (Div. 2)A-C

传送门 目录 A. Flip Flop Sum 代码&#xff1a; B. The Forbidden Permutation 代码&#xff1a; C. Flexible String 代码&#xff1a; A. Flip Flop Sum 题意&#xff1a;给你一个长度为n的数组&#xff08;数组元素只为1或者-1&#xff09;&#xff0c;你要且只能进行…...

机器学习笔记之近似推断(一)从深度学习角度认识推断

机器学习笔记之近似推断——从深度学习角度认识推断引言推断——基本介绍精确推断难的原因虽然能够表示&#xff0c;但计算代价太大无法直接表示引言 本节是一篇关于推断总结的博客&#xff0c;侧重点在于深度学习模型中的推断任务。 推断——基本介绍 推断(Inference\text{…...

指针的进阶

一、字符指针 int main() {char ch w;char* pc &ch;//pc就是字符指针//const char *p "abcdef";//这里其实是把字符串"abcdef"的首地址放入了指针p中//*p w;//这是错误的无法修改值&#xff08;可以看到这里绿色波浪线警告&#xff09;char arr[] …...

一元二次方程方程的类

1 问题设计一个一元二次方程的类&#xff0c;其中包括能够反映一元二次方程的属性与操作行为&#xff0c;然后再设计一个测试类&#xff0c;检测类的使用情况。2 方法使用package语句将方程的属性即计算跟的方法封装在一个有包名的类中&#xff0c;包名为tom.jiafei&#xff0c…...

Ask林曦|来回答,30个你关心的日常问题(二)

在林曦老师的线上书法直播课上&#xff0c;上课前后的聊天时间里&#xff0c;时常有同学向林曦老师提问&#xff0c;这些问题涵盖了日常生活的诸多方面&#xff0c;从身体的保养&#xff0c;到快乐的法门&#xff0c;皆是大家感兴趣的&#xff0c;也都共同关切的。   暄桐教室…...

哪款电容笔适合开学季?电容笔和Apple Pencil的区别

其实&#xff0c;市场上一般的电容笔和Apple Pencil的最大差别&#xff0c;就在于Apple Pencil与普通电容笔两者的重量和压感。然而&#xff0c;由于苹果电容笔价格过高&#xff0c;目前电容笔的市场份额逐渐转向平替电容笔&#xff0c;平替电容笔其性能也逐渐得到改善。下面&a…...

Qt之Qprocess

QProcess 可用于完成启动外部程序&#xff0c;并与之交互通信。 一、启动外部程序的两种方式   1&#xff09;一体式&#xff1a;void QProcess::start(const QString & program,const QStringList &arguments,OpenMode mode ReadWrite)     外部程序启动后&…...