在写springboot项目中遇到一个问题,下面的categoryList.stream()那一行代码中,为何如果左面用回categoryList变量接受结果会导致categoryList变为空,如果不接收就可以正常实现功能。
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
@Autowired
private ArticleService articleService;
@Override
public ResponseResult getCategoryList() {
//查询文章表状态为已发布的文章
LambdaQueryWrapper<Article> articleWrapper = new LambdaQueryWrapper<>();
articleWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
List<Article> articleList = articleService.list(articleWrapper);
//获取文章的分类id,去重 set可去重
Set<Long> categoryIds = articleList.stream()
// .map(article -> article.getCategoryId());
.map(Article::getCategoryId)
.collect(Collectors.toSet());
//查询分类表
List<Category> categoryList = listByIds(categoryIds);
//筛选出状态正常的目录
**/**/ categoryList=categoryList.stream(). //这样会导致categoryList为空****
categoryList.stream().
filter(category -> SystemConstants.STATUS_NORMAL.equals(category.getStatus()))
.collect(Collectors.toList());
//封装vo
List<CategoryVo> categoryVos = BeanCopyUtils.copyBeanList(categoryList, CategoryVo.class);
return ResponseResult.okResult(categoryVos);
}
}
GPT的建议:问题出在你对Stream的使用方式上。让我们分析一下代码:
首先,你从数据库查询了文章列表,并提取了它们的分类ID,然后将这些ID存入了一个叫做 categoryIds
的集合。
接着,你使用 listByIds(categoryIds)
方法从数据库查询了相应的分类,并将结果存入了 categoryList
变量。
接下来,你尝试过滤 categoryList
,只保留具有特定状态(假设 "status" 是 Category
类的一个字段)的分类。
问题出在你提到的这行代码:
categoryList = categoryList.stream()
.filter(category -> SystemConstants.STATUS_NORMAL.equals(category.getStatus()))
.collect(Collectors.toList());
这里的问题在于你试图重新赋值 categoryList
变量,使用流操作的结果来替换原来的内容,从而导致它变为空。这是因为流(Stream)是一次性使用的。一旦你调用了一个终端操作(比如 collect(Collectors.toList())
),该流就被消耗了,你不能再次使用它。
要解决这个问题,你可以避免重新赋值 categoryList
变量,而是直接在流操作中应用过滤器,不将结果重新赋值给同一个变量。这样修改代码如下:
List<Category> filteredCategories = categoryList.stream()
.filter(category -> SystemConstants.STATUS_NORMAL.equals(category.getStatus()))
.collect(Collectors.toList());
通过使用一个新的变量 filteredCategories
来存储过滤后的结果,你就不会丢失原来的 categoryList
。
或者,你可以直接在从数据库查询分类时就应用过滤器,使用 LambdaQueryWrapper
的 eq
方法。这样,你将只从数据库中获取符合特定状态的分类,而无需后续再用流来过滤。修改代码如下:
LambdaQueryWrapper<Category> categoryWrapper = new LambdaQueryWrapper<>();
categoryWrapper.eq(Category::getStatus, SystemConstants.STATUS_NORMAL);
List<Category> categoryList = list(categoryWrapper);
这样直接从数据库中获取状态为 "STATUS_NORMAL" 的分类,并将它们存入 categoryList
变量中。选择适合你需求和编码风格的方式进行修改。