IO练习Shop案例

Shop 案例学习

1.要求

实现Shop对商品的增删改查。
运用 集合 io来完成。
因为都是在文件中操作的所以考虑使用字符流,

2.功能实现逻辑

a. 插入

(Ⅰ)思路

需要把id,name,price 写入文件里,需要创建节点流 Writer(文件路径,是否覆盖),再创建处理流 BufferedWriter(节点流),调用处理流的write(String)往文件写入数据【需要考虑把int 型的 id 与price 与String 型的name 拼串,串之间留下“ ”】利用BufferedWriter的newLine方法换行。

(Ⅱ)代码

 private static void insert() {
        //循环判断输入商品编号是否存在
        Integer id = null;
        boolean flag = true;
        while (flag) {
            System.out.println("请输入商品编号");
            id = scanner.nextInt();
            final Integer i = id;
            Optional<Goods> first = findAllGoods().stream().filter(g -> g.getId() == i).findFirst();
            flag = first.isPresent();
            if (flag){
               System.out.println( "商品已存在");
            }
        }

        System.out.println("请输入商品名称:");
        String name = scanner.next();
        System.out.println("请输入商品价格:");
        int price = scanner.nextInt();
        //输入到a.txt文件的最后 注意这个问题写完要flush一下。
        writeGoods(Arrays.asList(new Goods(id,name,price)),true);

    }

b. 查找所有商品

思路

宏观思路在把文件读取到内存中,在内存中把数据还原成goodlist,在遍历展示,完成后需要在刷回到文件中。具体实现:利用Reader方法需要创建节点流,再创建处理流 BufferedReader(节点流),利用BufferedReader的readLine()方法逐行读入数据,直到下一行为空结束。读出的数据是一个字符串,可以使用String的split方法,根据“ ”把id name price分开,还原成Good对象,将其添加到list中,用增强for循环,遍历list。打印全部商品信息。

(Ⅱ)代码

private static void check() {

        //把商品信息输出到allGoods
        List<Goods> allGoods = findAllGoods();
        //遍历allGoods
        for (Goods goods : allGoods) {
            System.out.println(goods.getId() + " " + goods.getName() + " " + goods.getPrice());
        }
    }

c. 查看一个商品

思路

要求根据输入的id,查找对应的商品信息,思路与b.查找所有商品类似都是把文件转化成goodlist,通过stread.filter来筛选与输入id相同的商品,如果存在打印商品信息,否则输出不存在。

(Ⅱ)代码

private static void findOne() {
        System.out.println("请输入商品编号");
        int id = scanner.nextInt();
        //函数式编程根据ID查找商品
        Optional<Goods> first = findAllGoods().stream().filter(g -> g.getId() == id).findFirst();
        if (first.isPresent()) {
            Goods goods = first.get();
            System.out.println(goods.getId() + " " + goods.getName() + " " + goods.getPrice());
        }else {
            System.out.println("不存在");
        }

    }

d. 删除商品

思路

需要id,大概思路就是,拿到所有商品(重复代码已抽离返回一个商品的list),用迭代器迭代然后删除对应的商品信息,最后写回磁盘(这个操作也上方雷同所以做了代码的抽离)里。

(Ⅱ)代码

 private static void delete() {
        //输入ID 若商品存在?
        System.out.println("请输入商品编号");
        int id = scanner.nextInt();
        //用迭代器遍历找到删除
        List<Goods> allGoods = findAllGoods();
        Iterator<Goods> iterator =allGoods.iterator();
        while (iterator.hasNext()){
            Goods goods = iterator.next();
            if (goods.getId() == id){
                iterator.remove();
            }
        }
        //输入磁盘
        writeGoods(allGoods,false);
    }

e. 修改商品

思路

需要id,思路基本与删除操作一致,就是在迭代时要对具体产品信息做出修改而不是删除

(Ⅱ)代码

private static void update() {
        System.out.println("请输入商品编号");
        int id = scanner.nextInt();
        System.out.println("请输入商品名称:");
        String name = scanner.next();
        System.out.println("请输入商品价格:");
        int price = scanner.nextInt();
        //用迭代器找到
        List<Goods> allGoods = findAllGoods();
        Iterator<Goods> iterator = allGoods.iterator();
        while (iterator.hasNext()) {
            Goods goods = iterator.next();
            if (goods.getId() == id) {
                goods.setName(name);
                goods.setPrice(price);
            }
        }
        //输入磁盘
        writeGoods(allGoods, false);
    }

f. 退出操作

思路

这里主要是使用 System类的exit()方法:System.exit(-1);这个操作可以强制退出While(true)死循环

3.优化思路

a. 为甚么在拼串时,串之间留下“ ”?

答:一种标记的思路,就像在获取数组长度时,当指针指向“\o”时说明数组结束。同理“ ”用于在字符串中分割信息。

b.大量重复代码的抽离。

频繁的读取,写入操作,可以抽出来。

/**
     * 从磁盘中获取所有数据
     *
     * @return
     */
    private static List<Goods> findAllGoods() {
        ArrayList<Goods> allGoods = new ArrayList<>();
        //把商品信息输出到allGoods
        try (
                Reader reader = new FileReader(Shop.PATH);
                BufferedReader bufferedReader = new BufferedReader(reader)
        ) {
            String good;
            while ((good = bufferedReader.readLine()) != null) {
                //把good传入allGoods;
                String[] goodsElem = good.split(" ");
                Goods goods = new Goods(Integer.parseInt(goodsElem[0]),
                        goodsElem[1],
                        Integer.parseInt(goodsElem[2]));
                allGoods.add(goods);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return allGoods;
    }

    /**
     * 把数据输入文件中
     *
     * @return
     */
    private static void writeGoods(List<Goods> allGoods, Boolean append) {
        try (
                Writer writer = new FileWriter(Shop.PATH, append);
                BufferedWriter bufferedWriter = new BufferedWriter(writer);
        ) {
            for (Goods goods:allGoods) {
                bufferedWriter.write(goods.getId() + " " + goods.getName() + " " + goods.getPrice());
                bufferedWriter.newLine();
                bufferedWriter.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

4.遇到的问题

  • 最大的问题是对于些常见的类不熟悉,
  • 不同的数据类型之间转来转去很繁琐。
  • 选择合适的数据结构真的很重要。
posted @ 2022-06-24 09:45  小菜鸡的code之旅  阅读(27)  评论(0编辑  收藏  举报