问题描述
在写评论功能的时候,需要在返回的一级评论中保存它下面的二级评论
@RequestMapping("/findComment")
public List<Comment> findComment(int trendsid) {
List<Comment> commentList = commentService.findCommentOne(trendsid);//查询第一层评论
for (int i = 0 ; i < commentList.size() ; i ++){ //循环第一层的评论
Integer commentid = commentList.get(i).getCommentid(); //获取第一层评论的id
List<Comment> commentSon = commentService.findCommentSon(commentid); //根据评论的id查子评论
commentList.get(i).setCommentsSon(commentSon); //将结果保存
}
return commentList;
}
当i=0的时候,有两条子评论,但是当i=1的时候有1条子评论,这些子评论都能正常查出来,但是第二次给 commentList.get(i).setCommentSon(commentSon); 保存值时,连第一次保存的这个值也跟着变了。准确的说时在它的上一行,从service层把数据查出来的时候就已经变了。
很是苦恼。问人,找资料,摸索…花了一天多时间…
.
.
.
下面列举一下从当中了解到的知识点:
-
List中对象的存储
List中值为对象,并非基础数据类型,这些对象对应的内存中地址是一致的,commentSon的值改变后,内存地址并没有改变,所以导致保存的原单据值也是同样改变了 -
使用BeanUtils.clonebean(Object object) 克隆对象
把上面根据评论的id查子评论 查到的值 用这个克隆,确实是可以克隆出来一个新的对象,但还是一修改值全都跟着改变…(有可能是service返回的数据的问题) 而且这个克隆只会克隆一个对象,不会克隆里面的值
在使用这个方法之前要导入架包
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
List cloneList = (List)BeanUtils.cloneBean(commentSon);
- List的clone()方法,浅拷贝和深拷贝
一位热心网友推荐的博客,讲解了这个部分
https://blog.csdn.net/github_38687585/article/details/79926909
回归正题,上面我那个问题是怎么解决的呢?
通过修改代码,使用一个新的List把数据进行过度一下,不然不管是在controller还是在service克隆一个新的对象,最终它的地址都是同一个(这可能和service中方法书写的代码有关)
@RequestMapping("/findComment")
public List<Comment> findComment(int trendsid) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
List<Comment> commentList = commentService.findCommentOne(trendsid);//查询第一层评论
for (int i = 0 ; i < commentList.size() ; i ++){
Integer commentid = commentList.get(i).getCommentid(); //获取第一层评论的id
List<Comment> commentSon = new ArrayList<>();
List<Comment> test = commentService.findCommentSon(commentid); //根据评论的id查子评论
for (Comment comment : test) {
commentSon.add(comment);
}
commentList.get(i).setCommentsSon(commentSon); //将结果保存
}
return commentList;
}