递归
简单地说,就是如果在函数中存在着调用函数本身的情况,这种现象就叫递归;而在实际开发中,常见的递归使用场景有省市区父子级数据获取,树形菜单等。现在,我以Java递归获取省市区来实战一遍递归的使用场景
实现省市区树形数据展示
具体最终数据展示:
为了方便演示,不采用MySQL查询数据库,本地模拟省市区数据即可
- 区域类
import lombok.Data;
/**
* @Description
* @Author Fangchenjiang
* @Date 2021/8/19 16:24
*/
@Data
public class Region {
/**
* id
*/
private Integer id;
/**
* 区域名称
*/
private String areaName;
/**
* 区域类型:1-省区 2-市区,3-片区
*/
private Integer type;
/**
* 上级id
*/
private Integer superId;
public Region(Integer id, String areaName, Integer type, Integer superId) {
this.id = id;
this.areaName = areaName;
this.type = type;
this.superId = superId;
}
}
- 展示数据VO类
/**
* @Description
* @Author Fangchenjiang
* @Date 2021/8/19 16:36
*/
@Data
public class RegionTree {
/**
* id
*/
private Integer id;
/**
* 区域名称
*/
private String name;
/**
* 子节点
*/
private List<RegionTree>treeChild;
}
- Demo演示
/**
* @Description
* @Author Fangchenjiang
* @Date 2021/8/19 16:49
*/
public class MainTest {
public static void main(String[] args) {
List<Region> allRegion = getAllRegion();
List<RegionTree> regionTreeList = buildTree(allRegion, null, 3);
System.out.println(JSONObject.toJSONString(regionTreeList));
}
/**
* 构造父子级
*
* @param allRegion
* @param pid
* @return
*/
private static List<RegionTree> buildTree(List<Region> allRegion, Integer pid, Integer type) {
List<RegionTree> regionTreeList = new ArrayList<>();
//获取省
if (type.equals(1)) {
List<Region> regionList = allRegion.stream().filter(region -> region.getType().equals(1)).collect(Collectors.toList());
for (Region region : regionList) {
RegionTree regionTree = new RegionTree();
regionTree.setId(region.getId());
regionTree.setName(region.getAreaName());
regionTreeList.add(regionTree);
}
} else if (type.equals(2)) {
//获取省市
List<Region> regionList = allRegion.stream().filter(region -> region.getType().equals(1) || region.getType().equals(2)).collect(Collectors.toList());
for (Region region : regionList) {
RegionTree regionTree = new RegionTree();
if (Objects.equals(pid, region.getSuperId())) {
regionTree.setId(region.getId());
regionTree.setName(region.getAreaName());
regionTree.setTreeChild(buildTree(allRegion, region.getId(), type));
regionTreeList.add(regionTree);
}
}
} else {
//获取省市区
for (Region region : allRegion) {
RegionTree regionTree = new RegionTree();
if (Objects.equals(pid, region.getSuperId())) {
regionTree.setId(region.getId());
regionTree.setName(region.getAreaName());
regionTree.setTreeChild(buildTree(allRegion, region.getId(), type));
regionTreeList.add(regionTree);
}
}
}
return regionTreeList;
}
/**
* 获取总数据
*
* @return
*/
public static List<Region> getAllRegion() {
List<Region> regionList = new ArrayList<>();
regionList.add(new Region(1, "贵州省", 1, null));
regionList.add(new Region(11, "贵阳市", 2, 1));
regionList.add(new Region(12, "遵义市", 2, 1));
regionList.add(new Region(111, "观山湖区", 3, 11));
regionList.add(new Region(112, "花溪区", 3, 11));
regionList.add(new Region(121, "牡丹区", 3, 12));
regionList.add(new Region(122, "红花岗区", 3, 12));
regionList.add(new Region(2, "广东省", 1, null));
regionList.add(new Region(21, "广州市", 2, 2));
regionList.add(new Region(211, "天河区", 3, 21));
return regionList;
}
}
总结
递归不难理解,重点要注意省市区直接的联系,比如superId父级作为切入点,另外核心注意VO展示类的构造以及递归函数buildTree的使用;同理,如果遇到获取树形菜单,我们也可以依葫芦画瓢即可实现类似功能。