1. 程式人生 > 其它 >lambda表達是實現遞迴父節點與子節點的包含關係

lambda表達是實現遞迴父節點與子節點的包含關係

首先建立實體類表示與表結構的對應關係

/**
 * 商品三級分類
 * 
 * @author zhutong
 * @email [email protected]
 * @date 2021-08-27 10:40:19
 */
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 分類id
	 */
	@TableId
	private Long catId;
	/**
	 * 分類名稱
	 */
	private String name;
	/**
	 * 父分類id
	 */
	private Long parentCid;
	/**
	 * 層級
	 */
	private Integer catLevel;
	/**
	 * 是否顯示[0-不顯示,1顯示]
	 */
	private Integer showStatus;
	/**
	 * 排序
	 */
	private Integer sort;
	/**
	 * 圖示地址
	 */
	private String icon;
	/**
	 * 計量單位
	 */
	private String productUnit;
	/**
	 * 商品數量
	 */
	private Integer productCount;

	/**
	 * 目錄下的子目錄
	 */
	@TableField(exist = false) //此註解的意思是表中沒有這個欄位
	private List<CategoryEntity> children;

}

  然後就是普通的介面層

    /**
     * 查出所有分類以及子分類,以樹狀結構組裝起來
     */
    @RequestMapping("/list/tree")
    //@RequiresPermissions("product:category:list")
    public R list(){
        List<CategoryEntity> categoryEntities = categoryService.listWithTree();

        return R.ok().put("data", categoryEntities);
    }

  重點在於service層,利用lambda和遞迴實現,一定要注意lambda的行為引數化的寫法(詳見註釋)。lambda還是不夠熟悉,效能應該可以通過演算法進一步優化

@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listWithTree() {
        List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
        List<CategoryEntity> collect = categoryEntities.stream().filter(categoryEntity -> categoryEntity.getParentCid() == 0) //過濾出頂級節點,就是沒有父節點的節點
                .map(categoryEntity -> {
                    categoryEntity.setChildren(getChildren(categoryEntity, categoryEntities));
                    return categoryEntity;
                }).sorted(Comparator.comparingInt(item -> (item.getSort() == null ? 0 : item.getSort()))).collect(Collectors.toList());

        return collect;
    }

    /**
     * 找出父節點的所有子節點,遞迴實現,
     * 缺點每次都會遍歷所有的節點,感覺會影響效能,
     * 後期可能需要演算法提高效能
     * @param fatherCategoryEntity  父節點
     * @param all  所有節點
     *
     *             (item1, item2) -> {
     *                     return (item1.getSort() == null ? 0 : item1.getSort()) - (item2.getSort() == null ? 0 : item2.getSort());
     *                 }
     *
     *             Comparator.comparingInt(CategoryEntity::getSort)
     * @return
     */
    private List<CategoryEntity> getChildren(CategoryEntity fatherCategoryEntity,List<CategoryEntity> all){
        List<CategoryEntity> collect = all.stream().filter(categoryEntity -> categoryEntity.getParentCid() == fatherCategoryEntity.getCatId()) //過濾操作,
                .map(categoryEntity -> {
                    categoryEntity.setChildren(getChildren(categoryEntity, all)); //匹配操作,子節點下的位元組點
                    return categoryEntity;
                }).sorted(Comparator.comparingInt(item -> (item.getSort() == null ? 0 : item.getSort()))).collect(Collectors.toList()); //排序,lambda的行為引數化

        return collect;
    }