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

news2025/7/29 3:15:03

【实验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行代码关闭了输出流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/367933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络编程NIO

Java NIO&#xff08;New IO 或 Non Blocking IO&#xff09;是从Java 1.4 版本开始引入的一个新的IO API&#xff0c;可以替代标准的 Java IO API。NIO 支持面向缓冲区的、基于通道的 IO 操作。NIO 将以更加高效的方式进行文件的读写操作。 非阻塞 IO(NIO) 通过Selector去实…

ASP.NET Core MVC 项目 IOC容器

目录 一&#xff1a;什么是IOC容器 二&#xff1a;简单理解内置Ioc容器 三&#xff1a;依赖注入内置Ioc容器 四&#xff1a;生命周期 五&#xff1a;多种注册方式 一&#xff1a;什么是IOC容器 IOC容器是Inversion Of Control的缩写&#xff0c;翻译的意思就是控制反转。 …

【Azure 架构师学习笔记】-Azure Data Factory (3)-触发器详解-翻转窗口

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Data Factory】系列。 接上文【Azure 架构师学习笔记】-Azure Data Factory (2)-触发器 前言 上文中提到触发器的类型有以下4种&#xff0c;其中第一种【计划】是常用的&#xff0c; 与其他工具/服务类似的方式&#…

游戏、广告作底盘,价值直播为引擎,搜狐活在当下

2022年&#xff0c;中国互联网行业迎来了集体性的“中年危机”。 流量见顶、红利耗尽&#xff0c;再加上疫情的影响&#xff0c;国内互联网企业在过去一年真真实实地感受到了寒气。根据工信部数据&#xff0c;2022年&#xff0c;中国规模以上互联网和相关服务企业总收入达1.46…

【异构图笔记,篇章1】RGCN:Modeling Relational Data with Graph Convolutional Networks

【异构图笔记&#xff0c;篇章1】RGCN:Modeling Relational Data with Graph Convolutional Networks论文信息论文要点快览论文内容介绍背景任务RGCN Conv的介绍RGCN的trick论文实验结果实体分类链路预测评价及总结本文仅供学习&#xff0c;未经同意请勿转载 后期会陆续公开关于…

顺序表的增删查改

数据结构 是数据存储的方式&#xff0c;对于不同的数据我们要采用不同的数据结构。就像交通运输&#xff0c;选用什么交通工具取决于你要运输的是人还是货物&#xff0c;以及它们的数量。 顺序存储结构 包括顺序表、链表、栈和队列等。 例如腾讯QQ中的好友列表&#xff0c;…

运动蓝牙耳机什么款式最好、公认最好用的运动耳机推荐

如今大家对于运动越来越热衷&#xff0c;健身意识的逐渐加强&#xff0c;也带动了对运动装备的需求&#xff0c;其中运动蓝牙耳机也成为运动达人不可缺少的一部分了&#xff0c;在运动的过程中增加点音乐元素进来也会增多点动力。所以市面上出现了各种款式不一的运动耳机&#…

渗透测试之局域网信息探测实验

渗透测试之局域网信息探测实验实验目的一、实验原理1.1 SoftPerfect Network Scanner 流量监控软件二、实验环境2.1 操作机器2.2 SoftPerfectNetscan Scanner三、实验步骤1. 解压并运行SoftPerfect Network Scanner软件2. 使用SoftPerfect Network Scanner进行局域网信息探测实…

并发编程学习篇从0-1合集

一、synchronized 一、原子性、有序性、可见性 1.1 原子性 数据库的事务&#xff1a;ACID A&#xff1a;原子性-事务是一个最小的执行的单位&#xff0c;一次事务的多次操作要么都成功&#xff0c;要么都失败。 并发编程的原子性&#xff1a;一个或多个指令在CPU执行过程中…

JVM 锁优化和逃逸分析详解

1 锁优化JVM 在加锁的过程中&#xff0c;会采用自旋、自适应、锁消除、锁粗化等优化手段来提升代码执行效率。1.1 自旋锁和自适应自旋现在大多的处理器都是多核处理器 &#xff0c;如果在多核心处理器&#xff0c;有让两个或者以上的线程并行执行&#xff0c;我们可以让一个等待…

(免费分享)基于ssm的BBS社区论坛系统带论文

项目描述前台部分:1.用户注册登录模块用户登录后,可以进行发帖回帖功能,在线签到功能,完善个人信息,添加好友,收藏贴子,评论帖子,点赞功能,记录功能(比如记录今天发生的事情)等等…2.排行榜模块1.帖子讨论热度排行,分两种排行方式:(1) 根据用户今日发出的帖子被回复数量进行排名…

Linux USB 开发指南

文章目录Linux USB 开发指南1 前言1.1 文档简介1.2 目标读者1.3 适用范围2 模块介绍2.1 模块功能介绍2.2 相关术语介绍2.3 模块配置介绍2.3.1 Device Tree 配置说明2.3.2 board.dts 配置说明2.3.3 kernel menuconfig 配置说明2.4 源码结构介绍2.5 驱动框架介绍2.6 Gadget 配置2…

MySQL体系结构及数据库引擎

文章目录一、MYSQL的体系结构1、连接器2、查询缓存3、分析器&#xff08;要做什么&#xff09;4、优化器&#xff08;怎么做&#xff09;5、执行器6、数据库引擎1&#xff09;mysql支持的引擎2&#xff09;常用的mysql引擎比较3&#xff09;索引组织表、堆组织表4&#xff09;内…

大数据开发-Hive

1、hive简介 hive是基于Hadoop的一个数据仓库工具&#xff0c;用于分析数据的。可以将结构化数据文件映射为一张数据库表&#xff0c;并提供类SQL查询功能 注&#xff1a;hive-SQL or HQL or类SQL 和标准SQL还是有一点点区别的 本质是SQL转换为MapReduce程序 用途&#xff1…

Vulnhub靶场----6、DC-6

文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-6下载地址&#xff1a;https://download.vulnhub.com/dc/DC-6.zip kali&#xff1a;192.168.144.148 DC-6&#xff1a;192.168.144.154 靶机描述&#xff1a;选择带k01的密码后面会用到 访问192.168.144.154&…

秒杀测试案例 Java Redis Mysql

基于redis和MySQL乐观锁实现秒杀优惠券场景&#xff0c;一人一单。MySQL乐观锁改良控制不出现超卖和少卖问题&#xff0c;使用redisson分布式锁在用户维度加锁控制一人一单。 源码&#xff1a;https://github.com/hanhanhanxu/SeckillTest 文中图片看不清的地方可以鼠标右键-&…

01--微信小程序介绍

1、什么是微信小程序微信小程序&#xff0c;小程序的一种&#xff0c;英文名Wechat Mini Program&#xff0c;是一种不需要下载安装即可使用的应用&#xff0c;它实现了应用“触手可及”的梦想&#xff0c;用户扫一扫或搜一下即可打开应用。微信小程序是一种不需要下载安装即可…

python--排序总结

1.快速排序 a.原理 快速排序的基本思想是在待排序的 n 个元素中任取一个元素&#xff08;通常取第一个元素&#xff09;作为基准&#xff0c;把该元素放人最终位置后&#xff0c;整个数据序列被基准分割成两个子序列&#xff0c;所有小于基准的元素放置在前子序列中&#xff0…

Wireshark抓包

Wireshark 1 抓包时间显示格式 2 界面显示列设置 3 protocol协议解析 4 过滤器 tcp.port&#xff1a;TCP端口tcp.dstport&#xff1a;TCP目的端口tcp.srcport&#xff1a;TCP源端口udp.port&#xff1a;UDP端口udp.dstport&#xff1a;UDP目的端口udp.srcport&#xff1a;UDP…

HIVE --- 窗口函数

目录 简介 概念 数据准备 聚合函数over partition by子句 order by子句 window子句 窗口函数中的序列函数 ntile rank、dense_rank、row_number LAG、LEAD first_value、last_value 简介 本文主要介绍hive中的窗口函数.hive中的窗口函数和sql中的窗口函数相类似,都…