Spring Boot开发小而美的个人博客(李仁密) Bug1 评论重复

本文介绍了一种解决在博客评论系统中楼中楼评论出现重复现象的方法。通过调整递归逻辑,确保了每条评论只被添加一次,避免了重复显示的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在blog.html中展示评论时,起初很正常。但是,当楼中楼的评论多起来的时候,有部分评论会重复
效果如下:
在这里插入图片描述

先给解决方法

把原recursively(Comment)方法的 line 6 放到 line 7 的else分支中,如下:

    private void recursively(Comment comment) {
        tempReplys.add(comment);//顶节点添加到临时存放集合
        if (comment.getReplyComments().size() > 0) {
            List<Comment> replys = comment.getReplyComments();
            for (Comment reply : replys) {
//                tempReplys.add(reply);
//                if (reply.getReplyComments().size() > 0) {
//                    recursively(reply);
//                }
                if (reply.getReplyComments().size() > 0) {
                    recursively(reply);
                } else {
                    tempReplys.add(reply);
                }
            }
        }
    }

我们来分析一下原因:

回到CommentServiceImpl.java

    @Override
    public List<Comment> listCommentByBlogId(Long blogId) {
        Sort sort = Sort.by("createTime");
        List<Comment> commentList = commentRepository.findByBlogIdAndParentCommentNull(blogId, sort);
        return eachComment(commentList);
    }
    /**
     * 循环每个评论根节点
     */
    private List<Comment> eachComment(List<Comment> comments) {
        List<Comment> commentsView = new ArrayList<>();
        for (Comment comment : comments) {//重新copy一份,防止破坏原查询结果
            Comment c = new Comment();
            BeanUtils.copyProperties(comment, c);
            commentsView.add(c);
        }
        //合并评论的各层子代到第一级子代集合中
        combineChildren(commentsView);
        return commentsView;
    }

    /**
     * @param comments root根节点,blog不为空的对象集合
     * @return
     */
    private void combineChildren(List<Comment> comments) {

        for (Comment comment : comments) {
            List<Comment> replys1 = comment.getReplyComments();
            for (Comment reply1 : replys1) {
                //循环迭代,找出子代,存放在tempReplys中
                recursively(reply1);
            }
            //修改顶级节点的reply集合为迭代处理后的集合
            comment.setReplyComments(tempReplys);
            //清除临时存放区
            tempReplys = new ArrayList<>();
        }
    }

    //存放迭代找出的所有子代的集合
    private List<Comment> tempReplys = new ArrayList<>();

    /**
     * 递归迭代,剥洋葱
     *
     * @param comment 被迭代的对象
     * @return
     */
    private void recursively(Comment comment) {
        tempReplys.add(comment);//顶节点添加到临时存放集合
        if (comment.getReplyComments().size() > 0) {
            List<Comment> replys = comment.getReplyComments();
            for (Comment reply : replys) {
                tempReplys.add(reply);
                if (reply.getReplyComments().size() > 0) {
                    recursively(reply);
                }
            }
        }
    }

注意观察最后一个函数recursively(Comment),
当遍历到第三层子树(及以上)的时候,
step 1时,子树根节点添加进了tempReplys,
step 2进入递归
step 3时,子树根节点再一次被添加进了tempReplys。
在这里插入图片描述
连续添加两次子树根节点,肯定会重复。
这给我们一个启示,写代码的时候,要尽可能多考虑特殊情况~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值