2022-03-15 测试树状数据表

CREATE TABLE `category`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `pid` int(12) NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
@ResponseBody
@Controller
@RequestMapping("/category")
public class CategoryController {

    @Autowired
    private CategoryRepository categoryRepository;
    @GetMapping("/unsorted")
    public Page<Category> unsorted(@RequestParam(name="page",defaultValue="0")Integer page, @RequestParam(name="size",defaultValue="15") Integer size){
        //page:查询的页
        //size:每页显示的数量
        Pageable pageable = PageRequest.of(page,size) ;
        return categoryRepository.findAll(pageable);
    }

    @GetMapping("hierarchy")
    public List<CategoryHierarchyNode> findAll(){
        List<Category> unsorted = categoryRepository.findAll();

        int total = unsorted.size();
        return recursivelyBuildCategoryHierarchy(unsorted.toArray(new Category[total]), total);
    }
    
    public static class CategoryHierarchyNode extends Category {
        @javax.persistence.Transient
        private List<CategoryHierarchyNode> subCategories;

        public CategoryHierarchyNode() {
            subCategories = new ArrayList<>();
        }

        public List<CategoryHierarchyNode> getSubCategories() {
            return subCategories;
        }

        public void setSubCategories(List<CategoryHierarchyNode> categories) {
            subCategories = categories;
        }

        public void addSubCategory(CategoryHierarchyNode category) {
            subCategories.add(category);
        }
    }
    
    private static final List<CategoryHierarchyNode> EmptyList = new ArrayList<>();

    /**
     * 递归整理所有Category分类
     *
     * @param unsorted 待整理的结点
     * @param total 待整理的结点个数
     * @return CategoryHierarchy分类层级关系结构
     */
    private List<CategoryHierarchyNode> recursivelyBuildCategoryHierarchy(Category[] unsorted, int total) {
        if (total <= 0) {
            return EmptyList; // 递归终止条件1
        }

        // 哈希映射表, 方便搜索分类号ID
        Map<Integer, Integer> map = new HashMap<>();///< key为分类号ID整数,value为数组下标i(例如unsorted[i])
        for (int i = 0; i < total; i++) {
            int categoryId = unsorted[i].getId();
            map.put(categoryId, i);
        }

        // 无父母结点则为孤儿结点
        List<Integer> orphanCategoryList = new ArrayList<>();///< 存储无上级分类的孤儿分类,只记录分类ID号足矣

        // 有父母节点则为次级子节点
        Category[] normalCategoryList = new Category[total];///< 存储分类的节点

        // 遍历所有结点
        int cnt = 0;
        for (int i = 0; i < total; i++) {
            int parentCategoryId = unsorted[i].getPid();
            if (map.containsKey(parentCategoryId)) { // 检查上级结点是否存在
                normalCategoryList[cnt++] = unsorted[i]; // 有上级结点则当前为普通次级结点
                continue;
            }
            orphanCategoryList.add(unsorted[i].getId()); // 无父母则为孤儿结点
        }
        if (orphanCategoryList.size() <= 0 && cnt > 0) {
            // 递归终止条件2, 剩余结点中可能存在循环依赖式脏数据, 可以忽略之
            return EmptyList;
        }

        // 对剩余结点进行递归处理, 找出下一级子结点
        List<CategoryHierarchyNode> children =
                recursivelyBuildCategoryHierarchy(normalCategoryList, cnt);

        // 创建新的List列表, 用于输出分层结果
        List<CategoryHierarchyNode> hierarchy = new ArrayList<>(); // 变长数组, 以数组形式存放分类层级关系树
        Map<Integer, Integer> where = new HashMap<>(); // key=CategoryID号, value=数组下标j(例如hierarchy[j])
        int j = 0;
        for (Integer categoryId : orphanCategoryList) {
            int i = map.get(categoryId);

            CategoryHierarchyNode node = new CategoryHierarchyNode();
            node.setId(unsorted[i].getId());
            node.setName(unsorted[i].getName());
            node.setPid(unsorted[i].getPid());

            hierarchy.add(node);
            where.put(categoryId, j++);
        }
        // 遍历所有子节点, 放入树状结果并返回给上一级递归函数
        for (CategoryHierarchyNode child : children) {
            int parentCategoryId = child.getPid();
            j = where.get(parentCategoryId);
            hierarchy.get(j).addSubCategory(child);
        }
        return hierarchy;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值