软件工程实践第二次作业——个人实战

这个作业属于哪个课程软件工程实践-2023学年-W班
这个作业要求在哪里软件工程实践第二次作业——个人实战
这个作业的目标用java实现对json文件处理的实战小作业

一、Gitcode项目地址

项目地址

二、PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2020
• Estimate• 估计这个任务需要多少时间105
Development开发500450
• Analysis• 需求分析 (包括学习新技术)120120
• Design Spec• 生成设计文档2020
• Design Review• 设计复审1010
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)2020
• Design• 具体设计2030
• Coding• 具体编码360400
• Code Review• 代码复审2020
• Test• 测试(自我测试,修改代码,提交修改)6070
Reporting报告3040
• Test Repor• 测试报告1010
• Size Measurement• 计算工作量105
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划1010
合计12201230

三、解题思路描述

3.1处理JSON数据

经过上网查阅资料之后,采用Jackson库来处理JSON文件。
先创建Jackson的ObjectMapper对象,再使用readTree()方法创建JsonNode,获得了一个存有对应文件的JSON数据的JsonNode。
由于JSON数据是已经提前排序好的,用get方法找到所需的数据之后就可以进行其他操作了。

3.2对输入指令的检验

对players这个指令的检验较为简单,对result指令后面所跟的指令是否正确,采取了如下的处理方法:
先得到input.txt文件中的每一行,对每一行都进行split(" ")操作去除一个空格并存在数组中,这样可以获得一个单词数组。
再把需要比较正确性的单词用join方法连成一个字符串,再和已有的赛事作比较,看是否有这个赛事以检查指令的准确性。

3.3文件读写方式

采用BufferedWriter和Files.readAllLines的方法来进行文件的读写。

四、接口设计和实现过程

设计了三个类,分别为DWASearch、Result、Player。DWASearch类包含主函数和对文件读写的处理,Reslut和Player是包含比赛结果和选手信息的两个实体类,用于存储Json里所需的相关信息,都包含了处理Json文件获得List的方法,具体代码在第五点中展示。

五、关键代码展示

5.1 功能一相关代码

    /**
     * 获取运动员信息
     *
     * @param path
     * @return
     */
    public static List<Player> readJsonToPlayers(String path)
    {
        //  D:/javaworkplace/222100211/src/data/athletes.json
        ObjectMapper objectMapper = new ObjectMapper();
        List<Player> players = new ArrayList<>();
        try
        {
            //读取json文件
            JsonNode jsonNode = objectMapper.readTree(new File(path));
            //判断根节点是否为数组
            if (jsonNode.isArray())
            {
                for (JsonNode country : jsonNode)
                {
                    //获取并处理Participations数组
                    for (JsonNode player : country.get("Participations"))
                    {
                        //获取一个player的相关信息
                        Player p = new Player(player.get("Gender").asInt(), player.get("PreferredLastName").asText(),
                                player.get("PreferredFirstName").asText(), player.get("NAT").asText());
                        players.add(p);
                    }
                }
            }
        } catch (IOException e)
        {
            throw new RuntimeException(e);
        }
        return players;
    }

5.2 功能二相关代码


    /**
     * 获得某个赛事决赛的结果
     */
    public static List<Result> getResults(String path) throws IOException
    {
        //  D:/javaworkplace/222100211/src/data/
        ObjectMapper mapper = new ObjectMapper();
        List<Result> results = new ArrayList<>();
        JsonNode jsonNode = mapper.readTree(new File(path));
        for (JsonNode heats : jsonNode.get("Heats"))
        {
            if (heats.get("Name").asText().equals("Final"))
            {
                for (JsonNode jsonResult : heats.get("Results"))
                {
                    //获取信息
                    String fullName = jsonResult.get("FullName").asText();
                    int rank = jsonResult.get("Rank").asInt();
                    ArrayList<Double> scores = new ArrayList<>();
                    for (JsonNode dives : jsonResult.get("Dives"))
                    {
                        scores.add(dives.get("DivePoints").asDouble());
                    }
                    Result result = new Result(fullName, rank, scores);
                    results.add(result);
                }
            }
        }
        return results;
    }

5.3 主函数相关代码

public static void main(String[] args) throws IOException
    {
        // 检查是否有命令行参数
        if (args.length > 0)
        {
            //输入和输出的文件路径
            String input = args[0];
            String output = args[1];

            // 打开输入流
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(output)))
            {
                // 读取文件的所有行并存储到列表中
                List<String> lines = Files.readAllLines(Paths.get(input));

                // 遍历列表中的每一行
                for (String line : lines)
                {
                    //去除一个" ",以检验指令格式是否正确
                    String[] strings = line.split(" ");

                    //检查指令开头
                    switch (strings[0])
                    {
                        case "players":
                            if (strings.length==1)
                            {
                                List<Player> players = Player.readJsonToPlayers("src/data/athletes.json");
                                for (Player player : players)
                                {
                                    writer.write(player.printString());
                                }
                            }
                            break;
                        case "result":
                            if (strings.length==1)
                            {
                                writer.write("N/A\n");
                                writer.write("-----\n");
                                break;
                            }
                            else
                            {
                                //复制strings之后合并成一个String
                                String[] copy= Arrays.copyOfRange(strings,1,strings.length);

                                String name = String.join(" ", copy);

                                //查询是否有这个比赛
                                if (Result.isCompetition(name))
                                {
                                    System.out.println(name);
                                    List<Result> results = Result.getResults("src/data/"+name+".json");
                                    for (Result result : results)
                                    {
                                        writer.write(result.printString());
                                    }
                                }
                                else
                                {
                                    writer.write("N/A\n");
                                    writer.write("-----\n");
                                    break;
                                }
                            }
                            break;
                        default:
                            writer.write("ERROR\n");
                            writer.write("-----\n");
                            break;
                    }
                }
            } catch (IOException e)
            {
                throw new RuntimeException(e);
            }
        }
        else
        {
            System.out.println("没有提供命令行参数。");
        }
    }

六、性能改进

原本在主函数中每从input.txt读取一条指令,就开启一个输入流,采用一次请求一次输出的方式。
之后改为一次性读取input.txt的每一条指令,然后提前开启BufferedWriter做统一处理,这样就不会开启多个BufferedWriter,这样逻辑更清晰,也提升了性能。

七、单元测试

采用junit的单元测试方式,编写了测试类PlayerTest对Player类的方法进行测试

在这里插入图片描述

八、异常处理

在打开BufferedWriter时用try catch包围

读取json文件时捕获抛出异常

 try
        {
            //读取json文件
            JsonNode jsonNode = objectMapper.readTree(new File(path));
            //判断根节点是否为数组
            if (jsonNode.isArray())
            {
                for (JsonNode country : jsonNode)
                {
                    //获取并处理Participations数组
                    for (JsonNode player : country.get("Participations"))
                    {
                        //获取一个player的相关信息
                        Player p = new Player(player.get("Gender").asInt(), player.get("PreferredLastName").asText(),
                                player.get("PreferredFirstName").asText(), player.get("NAT").asText());
                        players.add(p);
                    }
                }
            }
        } catch (IOException e)
        {
            throw new RuntimeException(e);
        }

九、心得体会

1、初步掌握用Jackson处理JSON的方法,取得所需的某一部分数据;并再次运用文件输入输出的相关知识,提高了对文件的处理能力。
2、学会了添加框架支持。
3、认识到了封装的重要性,对封装的作用有了更深理解,以实现代码和数据的复用。

  • 26
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值