Java后台管理应用:如何在树结构上做模糊查询?

开发企业后台管理应用时,经常会遇到一种场景:在树结构上做模糊查询。
比如:公司组织架构树、分类树等,通常是在页面上的文本框中输入一个关键字,例如"数据",然后在公司组织架构树中过滤出名字包含数据的部门,且保持树结构不变。
公司的一级部门、二级部门、三级部门等等,名字都有可能包含"数据",比如一级部门叫大数据部门,二级部门叫数据分析部门或数据开发部门等等,这些都是符合要求的。

下面我将造出一个简单的分类树,并实现在树结构上模糊查询的功能(这里为了简单,将树的层级固定为三级,但实际上树的层级是未知的且远远不止三级,那就需要用到递归了)。
分类实体:

class Category{
    private String name;
    private List<Category> children;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Category> getChildren() {
        return children;
    }
    public void setChildren(List<Category> children) {
        this.children = children;
    }
}

分类树json格式的数据[tree.json]:

[
  {
    "name": "JAVA",
    "children": [
      {
        "name": "JAVA程序员",
        "children": [
          {
            "name": "开发工程师"
          },
          {
            "name": "技术总监"
          }
        ]
      },
      {
        "name": "JAVA大数据",
        "children": [
          {
            "name": "离线处理"
          },
          {
            "name": "实时处理"
          }
        ]
      },
      {
        "name": "JAVA架构",
        "children": [
          {
            "name": "高可用架构"
          },
          {
            "name": "高并发架构"
          }
        ]
      }
    ]
  },
  {
    "name": "大数据工程师",
    "children": [
      {
        "name": "大数据开发",
        "children": [
          {
            "name": "离线计算"
          },
          {
            "name": "实时计算"
          }
        ]
      },
      {
        "name": "大数据运维",
        "children": [
          {
            "name": "平台搭建"
          },
          {
            "name": "数据指标监控"
          }
        ]
      },
      {
        "name": "大数据分析",
        "children": [
          {
            "name": "用户画像分析"
          },
          {
            "name": "数据指标分析"
          }
        ]
      }
    ]
  }
]

main方法:

// 读取json文件,将其反序列化为Java的List对象
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(Test.class.getResourceAsStream("/tree.json")));
        String line;
        while (null != (line = reader.readLine())){
            sb.append(line).append("\n");
        }
        reader.close();
        List<Category> oneCategoryList = JSONArray.parseArray(sb.toString(), Category.class);
        // 定义模糊查询关键词
        String keyword = "开发";
        // 树结构模糊查询核心逻辑
        treeMatch(oneCategoryList,keyword);
        // 输出模糊查询后的树的样子
        System.out.println(JSONArray.toJSONString(oneCategoryList));

三级树结构模糊查询核心逻辑:

public static void treeMatch(List<Category> oneCategoryList,String keyword){
        Iterator<Category> oneIter = oneCategoryList.iterator();
        while (oneIter.hasNext()){
            Category oneCategory = oneIter.next();
            // 如果包含则什么也不做(不移除),否则就看二级目录
            if(!oneCategory.getName().contains(keyword)){
                List<Category> twoCategoryList = oneCategory.getChildren();
                Iterator<Category> twoIter = twoCategoryList.iterator();
                while (twoIter.hasNext()){
                    Category twoCategory = twoIter.next();
                    // 如果包含则什么也不做(不移除),否则就看三级目录
                    if(!twoCategory.getName().contains(keyword)){
                        List<Category> threeCategoryList = twoCategory.getChildren();
                        Iterator<Category> threeIter = threeCategoryList.iterator();
                        while (threeIter.hasNext()){
                            Category threeCategory = threeIter.next();
                            if(!threeCategory.getName().contains(keyword)){
                                threeIter.remove();
                            }
                        }
                        // 三级目录看完了,如果三级目录全部被移除,则移除二级目录
                        if(CollectionUtils.isEmpty(twoCategory.getChildren())){
                            twoIter.remove();
                        }
                    }
                }
                // 二级目录看完了,如果二级目录全部被移除,则移除一级目录
                if(CollectionUtils.isEmpty(oneCategory.getChildren())){
                    oneIter.remove();
                }
            }
        }
    }

当关键字为"开发时",运行程序,得到的结果如下。

[
	{
		"children": [
			{
				"children": [
					{
						"name": "开发工程师"
					}
				],
				"name": "JAVA程序员"
			}
		],
		"name": "JAVA"
	},
	{
		"children": [
			{
				"children": [
					{
						"name": "离线计算"
					},
					{
						"name": "实时计算"
					}
				],
				"name": "大数据开发"
			}
		],
		"name": "大数据工程师"
	}
]

本人已经验证过是没有问题的,如果疑问欢迎指正。

下面给出递归方式模糊查询的代码。

/**
  * 递归方法
  * @param anyLevelCategoryList 任意层级的目录集合
  * @param keyword 关键字
  */
 public static void treeMatch(List<Category> anyLevelCategoryList, String keyword){
     Iterator<Category> iter = anyLevelCategoryList.iterator();
     while (iter.hasNext()){
         // 获取当前遍历到的目录
         Category category = iter.next();
         // 如果当前目录名称包含关键字,则什么也不做(不移除),否则就看下一级
         if(!category.getName().contains(keyword)){
             // 取出下一级目录集合
             List<Category> childrenCategoryList = category.getChildren();
             // 递归
             if(!CollectionUtils.isEmpty(childrenCategoryList)){
                 treeMatch(childrenCategoryList,keyword);
             }
             // 下一级目录看完了,如果下一级目录全部被移除,则移除当前目录
             if(CollectionUtils.isEmpty(category.getChildren())){
                 iter.remove();
             }
         }
     }
 }

输入数据格式如下:
在这里插入图片描述
假如查询的关键字是“曹”,运行,输出结果如下。
在这里插入图片描述
验证通过。

  • 7
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波波老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值