关于Springboot中一个List的问题,如何解决?

在写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的使用方式上。让我们分析一下代码:

  1. 首先,你从数据库查询了文章列表,并提取了它们的分类ID,然后将这些ID存入了一个叫做 categoryIds 的集合。

  2. 接着,你使用 listByIds(categoryIds) 方法从数据库查询了相应的分类,并将结果存入了 categoryList 变量。

  3. 接下来,你尝试过滤 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

或者,你可以直接在从数据库查询分类时就应用过滤器,使用 LambdaQueryWrappereq 方法。这样,你将只从数据库中获取符合特定状态的分类,而无需后续再用流来过滤。修改代码如下:

LambdaQueryWrapper<Category> categoryWrapper = new LambdaQueryWrapper<>();
categoryWrapper.eq(Category::getStatus, SystemConstants.STATUS_NORMAL);
List<Category> categoryList = list(categoryWrapper);

这样直接从数据库中获取状态为 "STATUS_NORMAL" 的分类,并将它们存入 categoryList 变量中。选择适合你需求和编码风格的方式进行修改。

https://blog.csdn.net/weixin_53742691/article/details/131872400?spm=1001.2014.3001.5501%E6%98%AF%E6%B6%89%E5%8F%8A%E5%88%B0%E5%88%B0%E4%BA%86%E6%B7%B1%E6%B5%85%E6%8B%B7%E8%B4%9D%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%8C%E5%A4%A7%E6%A6%82%E7%9C%8B%E4%B8%80%E4%B8%8B%E4%BD%A0%E5%B0%B1%E4%BC%9A%E6%98%8E%E7%99%BD