1. 递归查询树tree结构有两种做法:
第一种,递归查询数据库结构,
第二种,一次性将数据库表中的所有数据查出来,然后再递归查出来的list集合,
第一种做法适合数据量较少的tree结构,因为要一直查询数据库数据量大时速度回相对较慢,所以数据量大时建议使用第二种方法,如图1所示是一个常见的树tree结构
图1
2. 反向递归(逆向递归)查询树tree结构根据关键字过滤数据
大家有么有遇到过这个问题:我想要根据关键字过滤查询出相关数据和它的上级结构,得到图1所示结果,可往往不知道怎么做,查不出上级结构总是得到图3类似的结构,要解决这个比较常见的问题就要用到反向递归的算法,网上我那个网搜不到类似的解决方案,本人一时兴趣来了,做了一套递归和反递归的解决方案,简单易懂,大家可以相互交流一下
图2
图3
3.示例代码
/** * 说明方法描述:将list转为树tree结构 * * @param allRrecords * @return * @time 2016年5月10日 下午6:00:35 * @author yangdong */ public List<Record> useListRecordToTree(List<Record> allRrecords) { List<Record> listParentRecord = new ArrayList<Record>(); List<Record> listNotParentRecord = new ArrayList<Record>(); // 第一步:遍历allRrecords保存所有数据的uuid用于判断是不是根节点 Map<String, String> mapAllUuid = new HashMap<String, String>(); Map<String, Record> allRecordMap = new HashMap<String, Record>(); for (Record record : allRrecords) { mapAllUuid.put(record.getStr("uuid"), record.getStr("uuid")); allRecordMap.put(record.getStr("uuid"), record); } // 第二步:遍历allRrecords找出所有的根节点和非根节点 if (allRrecords != null && allRrecords.size() > 0) { for (Record record : allRrecords) { if (StringUtil.isBlank(record.getStr("parent_uuid")) || !mapAllUuid.containsKey(record.getStr("parent_uuid"))) { listParentRecord.add(record); } else { listNotParentRecord.add(record); } } } // 第三步: 递归获取所有子节点 if (listParentRecord.size() > 0) { for (Record record : listParentRecord) { // 添加所有子级 record.set("childs", this.getTreeChildRecord(listNotParentRecord, record.getStr("uuid"))); } } return listParentRecord; } /** * 说明方法描述:使list转换为树并根据关键字和节点名称过滤 * * @param allRecords 所有节点 * @param keywords 要过滤的关键字 * @param filterFields 要过滤的字段 * @return * @time 2016年5月19日 下午3:27:32 * @author yangdong */ public List<Record> useListRecordToTreeByKeywords(List<Record> allRecords, String keywords, String... filterFields) { List<Record> listRecord = new ArrayList<Record>(); Map<String, Record> allRecordMap = new HashMap<String, Record>(); for (Record record : allRecords) { allRecordMap.put(record.getStr("uuid"), record); } // 遍历allRrecords找出所有的nodeName和关键字keywords相关的数据 if (allRecords != null && allRecords.size() > 0) { if (filterFields.length > 1) { for (Record record : allRecords) { for (String field : filterFields) { // 比较 if (record.getStr(field).toLowerCase().indexOf(keywords.toLowerCase()) != -1) { listRecord.add(record); } } } } else { for (Record record : allRecords) { // 比较 if (record.getStr(filterFields[0]).toLowerCase().indexOf(keywords.toLowerCase()) != -1) { listRecord.add(record); } } } } // 查找过滤出来的节点和他们的父节点 listRecord = this.getSelfAndTheirParentRecord(listRecord, new ArrayList<Record>(), new HashMap<String, Record>(), allRecordMap); // 将过滤出来的数据变成树tree结构 listRecord = this.useListRecordToTree(listRecord); return listRecord; } /** * 说明方法描述:递归查询子节点 * * @param childList 子节点 * @param parentUuid 父节点id * @return * @time 2016年5月10日 下午3:29:35 * @author yangdong */ private List<Record> getTreeChildRecord(List<Record> childList, String parentUuid) { List<Record> listParentRecord = new ArrayList<Record>(); List<Record> listNotParentRecord = new ArrayList<Record>(); // 遍历tmpList,找出所有的根节点和非根节点 if (childList != null && childList.size() > 0) { for (Record record : childList) { // 对比找出父节点 if (StringUtil.equals(record.getStr("parent_uuid"), parentUuid)) { listParentRecord.add(record); } else { listNotParentRecord.add(record); } } } // 查询子节点 if (listParentRecord.size() > 0) { for (Record record : listParentRecord) { // 递归查询子节点 record.set("childs", getTreeChildRecord(listNotParentRecord, record.getStr("uuid"))); } } return listParentRecord; } /** * 说明方法描述:递归找出本节点和他们的父节点 * * @param parentList 根据关键字过滤出来的相关节点的父节点 * @param resultList 返回的过滤出来的节点 * @param filterRecordMap 已经过滤出来的节点 * @param allRecordMap 所有节点 * @return * @time 2016年5月19日 上午9:53:56 * @author yangdong */ private List<Record> getSelfAndTheirParentRecord(List<Record> parentList, List<Record> resultList, Map<String, Record> filterRecordMap, Map<String, Record> allRecordMap) { // 当父节点为null或者节点数量为0时返回结果,退出递归 if (parentList == null || parentList.size() == 0) { return resultList; } // 重新创建父节点集合 List<Record> listParentRecord = new ArrayList<Record>(); // 遍历已经过滤出来的节点 for (Record record : parentList) { String uuid = record.getStr("uuid"); String parent_uuid = record.getStr("parent_uuid"); // 如果已经过滤出来的节点不存在则添加到list中 if (!filterRecordMap.containsKey(uuid)) { listParentRecord.add(record);// 添加到父节点中 filterRecordMap.put(uuid, record);// 添加到已过滤的map中 allRecordMap.remove(uuid);// 移除集合中相应的元素 resultList.add(record);// 添加到结果集中 } // 找出本节点的父节点并添加到listParentRecord父节点集合中,并移除集合中相应的元素 if (StringUtil.isNotBlank(parent_uuid)) { Record parentRecord = allRecordMap.get(parent_uuid); if (parentRecord != null) { listParentRecord.add(parentRecord); allRecordMap.remove(parent_uuid); } } } // 递归调用 getSelfAndTheirParentRecord(listParentRecord, resultList, filterRecordMap, allRecordMap); return resultList; }
//示例
/** * 说明方法描述:递归查询所有权限 * * @param keyword * @param is_deleted * @return * @time 2016年5月10日 下午3:47:50 * @author yangdong */ public List<Record> getRecordByKeywordRecursive(String keyword, String is_deleted) { // 第一步:查询所有的数据 StringBuffer sql = new StringBuffer( " select pa.uuid,pa.parent_uuid,pa.author_code,pa.author_name,pa.is_menu,pa.sort_number,pa.is_enable,pa.menu_icon "); sql.append(" from s_author pa"); List<Object> params = new ArrayList<Object>(); sql.append(" where pa.is_deleted=? "); params.add(is_deleted); sql.append(" order by pa.sort_number asc "); List<Record> allRrecords = Db.use(AppConst.DB_DATASOURCE_MAIN).find(sql.toString(), ParamUtil.listToArray(params));
//第二步:将list变为树tree结构 if (StringUtil.isNotBlank(keyword)) { return super.useListRecordToTreeByKeywords(allRrecords, keyword, "author_name"); } else { return super.useListRecordToTree(allRrecords); } }
----------------------------------------------------------------------------------------------------------------------------------------
如果您认为本教程质量不错,读后觉得收获很大,预期工资能蹭蹭蹭的往上涨,那么不妨小额赞助我一下,让我有动力继续写出高质量的教程。
----------------------------------------------------------------------------------------------------------------------------------------
Original url: Access
Created at: 2019-11-22 12:15:33
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论