一、树结构的三种组装方式(递归.双层for循环,map)
(1)递归
普通递归方法
public Result getBmsMenuList(UserSessionVO userSessionInfo) {
// 查询顶级节点菜单
List bmsMenuVOList = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO());
for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
getBmsMenuListByRecursion(bmsMenuVO);
}
return Result.createWithModels(null, bmsMenuVOList);
}
private void getBmsMenuListByRecursion(BmsMenuVO bmsMenuVO) {
List bmsMenuVOS = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO().setParentId(bmsMenuVO.getId()));
if (CollectionUtils.isEmpty(bmsMenuVOS)) {
return;
}
bmsMenuVO.setChildBmsMenuList(bmsMenuVOS);
for (BmsMenuVO menuVO : bmsMenuVOS) {
getBmsMenuListByRecursion(menuVO);
}
}
stream流递归方法
//获取父节点
List collect = trees.stream().filter(m -> m.getParentId() == 0).map(
(m) -> {
m.setChildren(getChildrenList(m, trees));
return m;
}
).collect(Collectors.toList());
/**
* 获取子节点列表
* @param tree
* @param list
* @return
*/
public static List getChildrenList(TreeSelect tree, List list){
List children = list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).map(
(item) -> {
item.setChildren(getChildrenList(item, list));
return item;
}
).collect(Collectors.toList());
return children;
}
(2)双层for循环
// 查询主节点
List bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);
// 拼装结果
List bmsMenuTree = new ArrayList();
for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
// 根节点的父Id为null
if (bmsMenuVO.getParentId() == null) {
bmsMenuTree.add(bmsMenuVO);
}
for (BmsMenuVO menuVO : bmsMenuVOList) {
if (menuVO.getParentId() != null && menuVO.getParentId().equals(bmsMenuVO.getId())) {
if (CollectionUtils.isEmpty(bmsMenuVO.getChildBmsMenuList())) {
bmsMenuVO.setChildBmsMenuList(new ArrayList());
}
bmsMenuVO.getChildBmsMenuList().add(menuVO);
}
}
}
// 返回结果
return Result.createWithModels(null, bmsMenuTree);
(3)map遍历
// 查询所有节点
List bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);
// 拼装结果
List bmsMenuTree = new ArrayList();
// 用来存储节点的子元素map
Map childBmsMenuMap = new LinkedHashMap();
for (BmsMenuVO menuVO : bmsMenuVOList) {
childBmsMenuMap.put(menuVO.getId(), menuVO);
}
for (Long bmsMenuId : childBmsMenuMap.keySet()) {
BmsMenuVO menuVO = childBmsMenuMap.get(bmsMenuId);
Long parentId = menuVO.getParentId();
if (parentId == null) {
bmsMenuTree.add(menuVO);
} else {
BmsMenuVO parentMenuVO = childBmsMenuMap.get(parentId);
if (parentMenuVO.g服务器托管网etChildBmsMenuList() == null) {
parentMenuVO.setChildBmsMenuList(new ArrayList());
}
parentMenuVO.getChildBmsMenuList().add(menuVO);
}
}
2、使用递归查询某个节点所在的树结构
使用场景:当我们得到一个树形结构数据时,可能需要在树形结构上对数据进行筛选,例如通过文件夹(文件)名称模糊查询相关的文件夹并展现其父级。
缺点:需要查询出完整的树形结构才能用作筛选,在数据量非常庞大的时候并不适用。
@Data
public class TreeDto {
private String id;
private String name;
private List subsetTreeDtoList;
public TreeDto(String id,String name,List subsetTreeDtoList){
this.id = id;
this.name = name;
this.subsetTreeDtoList = subsetTreeDtoList;
}
}
筛选
/**
* 树形筛选查找
* @param treeDtoList 树形集合
* @param idList 筛选条件(可以是其他条件)
* @return 包含的节点数据
*/
public static List screenTree(List treeDtoList, List idList){
//最后返回的筛选完成的集合
List screeningOfCompleteList = new ArrayList();
if (listIsNotEmpty(treeDtoList) && listIsNotEmpty(idList)){
for (TreeDto treeDto : treeDtoList){
List subsetList = treeDto.getSubsetTreeDtoList();
//递归筛选完成后的返回的需要添加的数据
TreeDto addTreeDto = getSubsetPmsPlanPo(treeDto,subsetList,idList);
if (isNotEmpty(addTreeDto)){
screeningOfCompleteList.add(addTreeDto);
}
}
return screeningOfCompleteList;
}
return null;
}
/**
* 筛选符合的集合并返回
* @param treeDto 树形类
* @param subsetTreeDtoList 子集集合
* @param idList 筛选条件
* @return 筛选成功的类
*/
public static TreeDto getSubsetPmsPlanPo(TreeDto treeDto,List subsetTreeDtoList,List idList){
//作为筛选条件的判断值
String id = treeDto.getId();
//有子集时继续向下寻找
if (listIsNotEmpty(subsetTreeDtoList)){
List addTreeDtoList = new ArrayList();
for (TreeDto subsetTreeDto : subsetTreeDtoList){
List subsetList = subsetTreeDto.getSubsetTreeDtoList();
TreeDto newTreeDto = getSubsetPmsPlanPo(subsetTreeDto,subsetList,idList);
//当子集筛选完不为空时添加
if (isNotEmpty(newTreeDto)){
addTreeDtoList.add(newTreeDto);
服务器托管网 }
}
//子集满足条件筛选时集合不为空时,替换对象集合内容并返回当前对象
if (listIsNotEmpty(addTreeDtoList)){
treeDto.setSubsetTreeDtoList(addTreeDtoList);
return treeDto;
//当前对象子集对象不满足条件时,判断当前对象自己是否满足筛选条件,满足设置子集集合为空,并返回当前对象
}else if (listIsEmpty(addTreeDtoList) && idList.contains(id)){
treeDto.setSubsetTreeDtoList(null);
return treeDto;
}else {
//未满足筛选条件直接返回null
return null;
}
}else {
//无子集时判断当前对象是否满足筛选条件
if (idList.contains(id)){
return treeDto;
}else {
return null;
}
}
}
/**
* 判断集合为空
* @param list 需要判断的集合
* @return 集合为空时返回 true
*/
public static boolean listIsEmpty(Collection list){
return (null == list || list.size() == 0);
}
/**
* 判断集合非空
* @param list 需要判断的集合
* @return 集合非空时返回 true
*/
public static boolean listIsNotEmpty(Collection list){
return !listIsEmpty(list);
}
/**
* 判断对象为null或空时
* @param object 对象
* @return 对象为空或null时返回 true
*/
public static boolean isEmpty(Object object) {
if (object == null) {
return (true);
}
if ("".equals(object)) {
return (true);
}
if ("null".equals(object)) {
return (true);
}
return (false);
}
/**
* 判断对象非空
* @param object 对象
* @return 对象为非空时返回 true
*/
public static boolean isNotEmpty(Object object) {
if (object != null && !object.equals("") && !object.equals("null")) {
return (true);
}
return (false);
}
public static void main(String[] args) {
TreeDto treeDto1 = new TreeDto("1","A",new ArrayList());
TreeDto treeDto1_1 = new TreeDto("1.1","A-A",new ArrayList());
TreeDto treeDto1_2 = new TreeDto("1.2","A-B",new ArrayList());
TreeDto treeDto1_3 = new TreeDto("1.3","A-C",new ArrayList());
treeDto1.getSubsetTreeDtoList().add(treeDto1_1);
treeDto1.getSubsetTreeDtoList().add(treeDto1_2);
treeDto1.getSubsetTreeDtoList().add(treeDto1_3);
TreeDto treeDto2 = new TreeDto("2","B",new ArrayList());
TreeDto treeDto2_1 = new TreeDto("2.1","B-A",new ArrayList());
TreeDto treeDto2_2 = new TreeDto("2.2","B-B",new ArrayList());
TreeDto treeDto2_3 = new TreeDto("2.3","B-C",new ArrayList());
TreeDto treeDto2_3_1 = new TreeDto("2.3.1","B-C-A",null);
treeDto2.getSubsetTreeDtoList().add(treeDto2_1);
treeDto2.getSubsetTreeDtoList().add(treeDto2_2);
treeDto2.getSubsetTreeDtoList().add(treeDto2_3);
treeDto2.getSubsetTreeDtoList().get(2).getSubsetTreeDtoList().add(treeDto2_3_1);
String[] array = {"1.3","2.2","2.3.1"};
List idList = Arrays.asList(array);
List treeDtoList = new ArrayList();
treeDtoList.add(treeDto1);
treeDtoList.add(treeDto2);
System.out.println(JSON.toJSONString(screenTree(treeDtoList,idList)));
}
}
返回结果为
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
在 PyTorch 中训练大语言模型不仅仅是写一个训练循环这么简单。我们通常需要将模型分布在多个设备上,并使用许多优化技术以实现稳定高效的训练。Hugging Face 🤗 Accelerate 的创建是为了支持跨 GPU 和 TPU 的分布式训练,并使其能够…