在一些商城项目中分类是帮助用户快速定位商品的属性,它可以帮助用户快速定位到他们感兴趣的商品,增加了网站的可用性和效率。那么如何去写好一个分类,从性能去分析考虑,这篇博客也许能更好的帮助到你。
首先我们还是按照自己项目的分类需求对分类进行划分比如:简单的一级分类(标签、分组),稍微复杂的一些的二三级分类(商品分类,各种大类拆分分类),多级层级分类(IM系统中无法确定的层级关系)。
public class Category { private String name; private String description; // 构造函数、getter和setter略 }这里的处理时间复杂度一般是O(1)
List<Category> catList = list(); if (CollUtil.isEmpty(catList)) { return null; } // 遍历这些信息,将父级分类和子级分类放到一个map中 List<Map<rCategory, List<rCategory>>> merCategoryVO = Lists.newArrayList(); // 暂存子级分类 Map<Integer, List<rCategory>> childList = new HashMap<>(); for (rCategory category : catList) { if (ObjUtil.equals(category.getRelevanceId(), 0)) { //父级分类 Map<rCategory, List<rCategory>> releaseMap = new HashMap<>(); releaseMap.put(category, Lists.newArrayList()); merCategoryVO.add(releaseMap); } else { List<rCategory> Categories = Optional.ofNullable(childList.get(category.getRelevanceId())) .orElse(Lists.newArrayList()); Categories.add(category); childList.put(category.getRelevanceId(), Categories); } } // 堆代码 duidaima.com // 按照父级分类的id,将子级分类放到对应的父级分类中 for (Map<rCategory, List<rCategory>> map : merCategoryVO) { map.keySet().forEach(key -> { List<rCategory> list = childList.get(key.getId()); if (CollUtil.isNotEmpty(list)) { map.put(key, list); } }); } return merCategoryVO; }实现效果如下示例:
public class Category { private int id; private int pid; private String name; private String description; private List<Category> subcategories; // 构造函数、getter和setter略 }实例dem:
public List<ProCategoryCacheVo> buildTree(){ List<ProCategoryCacheVo> treeCategory = new ArrayList<ProCategoryCacheVo>(); for(ProCategoryCacheVo categoryNode : getRootNode()) { categoryNode = buildChildTree(categoryNode); treeCategory.add(categoryNode); } return sortList(treeCategory); }首先调用的是getRootNode()方法去获取根节点,道理不变拿的还是我们提前约定好的根节点id
private List<ProCategoryCacheVo> getRootNode() { List<ProCategoryCacheVo> rootMenuLists = new ArrayList<ProCategoryCacheVo>(); for(ProCategoryCacheVo categoryNode : categoryList) { if(categoryNode.getPid().equals(0)) { rootMenuLists.add(categoryNode); } } return rootMenuLists; }然后我们根据每一个树形结点进入到递归算法中,填充我们获取到的内容
private ProCategoryCacheVo buildChildTree(ProCategoryCacheVo pNode){ List<ProCategoryCacheVo> rootMenuLists = new ArrayList<ProCategoryCacheVo>(); for(ProCategoryCacheVo categoryNode : categoryList) { if(ObjUtil.equals(categoryNode.getId(),pNode.getId())){ rootMenuLists.add(buildChildTree(categoryNode)); } } pNode.setSubcategories(rootMenuLists); return pNode; }那么到这里我们就算获取完成这个树形结构了。下面我们去扩展一下如果要对里面内容安装权重进行排序该如何去处理呢?
private List<ProCategoryCacheVo> sortList(List<ProCategoryCacheVo> treeMenus) { treeMenus = treeMenus.stream().sorted(Comparator.comparing(ProCategoryCacheVo::getSort).reversed()).collect(Collectors.toList()); treeMenus.forEach(e -> { if (CollUtil.isNotEmpty(e.getChildList())) { e.setChildList(sortList(e.getChildList())); } }); return treeMenus; }总结