java json树 快速查找_java集合快速构建成树形json

本文介绍了如何在Java中快速构建树形结构的JSON,特别是针对省市区等数据的树形展示。通过自定义节点转换器和根节点选择器,实现了代码无侵入性的树形结构构建,并给出了具体实现代码和示例。
摘要由CSDN通过智能技术生成

1 场景

1.1 面对问题

java中,经常会需要构建树形结构的json,如构建一个省市区的树形结构。

此处情况,有如下几个情况需要解决:

需要根据不同的前端组件,来定义不同格式的json(如easyui、ext里面的tree结构均不同)。如切换组件,原代码不适用

树形结构,需手动组装,如不同的树形结构太多,则会花较多的时间来组装不同业务的树形结构。

手动实现,代码较复杂,容易出问题

如让java中的实体类实现定义的树形结构的接口,代码侵入性太强

1.2 实现目标

这里实现一个代码工具,各位朋友可以参考下,实现如下功能:

实现树形结构的快速构建

定义不同树类型的实现,可切换树形结构简单

系统实体类无需实现自定义接口,代码无侵入性

使用类适配器,可随意自行扩展

2 代码结构图

eaad633066f5

代码结构图.png

3 实现效果

依赖model:

package com.sa.example.tree.bean;

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

/**

* 区域信息

*/

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Area {

private String areaCode;

private String areaName;

private Integer order;

private String parentCode;

}

3.1 调用

package com.sa.example.tree.test;

import com.sa.example.tree.*;

import com.sa.example.tree.ext.EasyuiNode;

import com.sa.example.tree.bean.Area;

import org.apache.commons.lang3.StringUtils;

import org.junit.Test;

import java.util.ArrayList;

import java.util.List;

public class TreeParseTest {

@Test

public void testParse(){

// 节点转换器(将任意对象转换为树节点)

NodeConvert departmentConverter = new NodeConvert() {

@Override

public Node convert(Area area) {

// 根据实体的属性,补充到对应的NodeInstance对象上(转换为EasyUi)

NodeInstance instance = new EasyuiNode();

instance.setParentCode(area.getParentCode());

instance.setCode(area.getAreaCode());

instance.setName(area.getAreaName());

instance.setOrder(area.getOrder());

// 根据实际业务,配置其他属性......

/*instance.setCss("icon-value");

instance.setChecked(true);

instance.setState("opened");

instance.putExtMap("aa", "aaVaule");*/

return instance;

}

};

// 默认根节点选择器(确定根节点)

RootSelector defaultSelector = new RootSelector() {

@Override

public boolean select(Node node) {

if (node != null && StringUtils.isEmpty(node.getParentCode())) {

return true;

}

return false;

}

};

List areaList = new ArrayList<>();

areaList.add(new Area("130000000000", "河北", 2, ""));

areaList.add(new Area("130100000000", "石家庄", 1, "130000000000"));

areaList.add(new Area("130400000000", "邯郸", 2, "130000000000"));

areaList.add(new Area("370000000000", "山东", 1, ""));

areaList.add(new Area("370100000000", "济南", 1, "370000000000"));

areaList.add(new Area("370200000000", "青岛", 2, "370000000000"));

areaList.add(new Area("370202000000", "市南", 2, "370200000000"));

areaList.add(new Area("370203000000", "市北", 3, "370200000000"));

TreeBuilder treeBuilder = new TreeBuilder<>(departmentConverter, defaultSelector);

Tree tree = treeBuilder.build(areaList);

System.out.println(tree.toJson());

}

}

3.2 结果

[{

"children": [{

"id": "370100000000",

"text": "济南"

}, {

"children": [{

"id": "370202000000",

"text": "市南"

}, {

"id": "370203000000",

"text": "市北"

}],

"id": "370200000000",

"text": "青岛"

}],

"id": "370000000000",

"text": "山东"

}, {

"children": [{

"id": "130100000000",

"text": "石家庄"

}, {

"id": "130400000000",

"text": "邯郸"

}],

"id": "130000000000",

"text": "河北"

}]

4 实现代码

maven依赖:

org.apache.commons

commons-lang3

3.11

org.apache.commons

commons-collections4

4.4

com.alibaba

fastjson

1.2.73

4.1 JSON转换器

/**

* JSON转换器

*/

public interface JsonParser {

/**

* 生成JSON对象

* @return JSON对象

*/

JSONObject toJson();

}

4.2 节点

package com.sa.example.tree;

import java.util.List;

import java.util.Map;

/**

* 节点

*/

public interface Node extends JsonParser, Comparable {

/**

* 获取节点代码

*

* @return

*/

String getCode();

/**

* 获取节点名称

*

* @return

*/

String getName();

/**

* 获取节点排序

*

* @return

*/

Integer getOrder();

/**

* 获取节点样式

*

* @return

*/

String getCss();

/**

* 获取节点状态

*

* @return

*/

String getState();

/**

* 获取节点复选状态

*

* @return

*/

Boolean getChecked();

/**

* 扩展属性

*

* @return

*/

Map getExtMap();

/**

* 获取父节点代码

*

* @return

*/

String getParentCode();

/**

* 获取子节点集合

*

* @return

*/

List getChildList();

@Override

default int compareTo(Node o) {

return this.getOrder().compareTo(o.getOrder());

}

/**

* 添加子节点

*

* @param node 子节点

*/

void addChildNode(Node node);

/**

* 设置额外属性

* @param key

* @param value

*/

void putExtMap(String key, Object value);

}

4.3 节点实例

package com.sa.example.tree;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

/**

* Node实例

*/

public abstract class NodeInstance implements Node {

/**

* 节点代码

*/

private String code;

/**

* 节点名称

*/

private String name;

/**

* 节点排序

*/

private Integer order;

/**

* 节点样式

*/

private String css;

/**

* 节点状态

*/

private String state;

/**

* 节点复选状态

*/

private Boolean checked;

/**

* 扩展属性

*/

private Map extMap;

/**

* 父节点代码

*/

private String parentCode;

/**

* 子节点集合

*/

private List childList;

@Override

public void addChildNode(Node node) {

if (childList == null) {

childList = new ArrayList<>();

}

childList.add(node);

}

@Override

public List getChildList() {

return childList;

}

@Override

public void putExtMap(String key, Object value) {

if (extMap == null) {

extMap = new HashMap<>();

}

extMap.put(key, value);

}

@Override

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

@Override

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public Integer getOrder() {

return order;

}

public void setOrder(Integer order) {

this.order = order;

}

@Override

public String getCss() {

return css;

}

public void setCss(String css) {

this.css = css;

}

@Override

public String getState() {

return state;

}

public void setState(String state) {

this.state = state;

}

@Override

public Boolean getChecked() {

return checked;

}

public void setChecked(Boolean checked) {

this.checked = checked;

}

@Override

public String getParentCode() {

return parentCode;

}

public void setParentCode(String parentCode) {

this.parentCode = parentCode;

}

@Override

public Map getExtMap() {

return extMap;

}

}

4.4 根节点选择器

package com.sa.example.tree;

/**

* 根节点选择器

*/

public interface RootSelector {

/**

* 选择节点为根节点

* @param node 被选择节点

* @return true:选择为根节点;false:不选择为根节点

*/

boolean select(Node node);

}

4.5 节点转换器

/**

* 节点转换器

*/

public interface NodeConvert {

/**

* 实体转换为节点

* @param t

* @return

*/

Node convert(T t);

}

4.6 树

package com.sa.example.tree;

import com.alibaba.fastjson.JSONArray;

import org.apache.commons.collections4.CollectionUtils;

import java.util.List;

/**

* 树

*/

public class Tree {

/**

* 根节点

*/

private List nodeList;

public Tree() {

}

public void setNodeList(List nodeList) {

this.nodeList = nodeList;

}

public String toJson() {

JSONArray jsonArray = new JSONArray();

if (CollectionUtils.isNotEmpty(nodeList)) {

for (Node node : nodeList) {

jsonArray.add(node.toJson());

}

}

return jsonArray.toJSONString();

}

}

4.7 树构建器

package com.sa.example.tree;

import org.apache.commons.collections4.CollectionUtils;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Iterator;

import java.util.List;

/**

* 树构建器

*

* @param

*/

public class TreeBuilder {

/**

* 节点转换器

*/

private NodeConvert nodeConvert;

/**

* 根节点选择器

*/

private RootSelector rootSelector;

public TreeBuilder(NodeConvert nodeConvert, RootSelector rootSelector) {

this.nodeConvert = nodeConvert;

this.rootSelector = rootSelector;

}

/**

* 初始化节点列表

*

* @return

*/

protected List initNodeList(List list) {

List nodeList = new ArrayList<>();

if (CollectionUtils.isNotEmpty(list)) {

for (T model : list) {

nodeList.add(nodeConvert.convert(model));

}

}

return nodeList;

}

/**

* 构建节点结构

*

* @param nodeList

* @return

*/

protected List buildNodeStructure(List nodeList) {

List rootList = new ArrayList<>();

if (CollectionUtils.isNotEmpty(nodeList)) {

// 1、构建root节点

Iterator iterator = nodeList.iterator();

while (iterator.hasNext()) {

Node node = iterator.next();

if (rootSelector.select(node)) {

rootList.add(node);

iterator.remove();

}

}

// 2、循环查找子节点

for (Node rootNode : rootList) {

this.buildChildNode(rootNode, nodeList);

}

}

return rootList;

}

/**

* 构建子节点(反复调用)

*

* @param parentNode 父节点

* @param originNodeList 自己节点列表

*/

protected void buildChildNode(Node parentNode, List originNodeList) {

if (CollectionUtils.isNotEmpty(originNodeList)) {

Iterator iterator = originNodeList.iterator();

while (iterator.hasNext()) {

Node node = iterator.next();

if (StringUtils.equals(parentNode.getCode(), node.getParentCode())) {

parentNode.addChildNode(node);

iterator.remove();

// 迭代调用

this.buildChildNode(node, originNodeList);

}

}

}

}

/**

* 节点集合排序

*

* @param nodeList

* @return

*/

protected void sortNodeList(List nodeList) {

if (CollectionUtils.isNotEmpty(nodeList)) {

Collections.sort(nodeList);

for (Node node : nodeList) {

if (CollectionUtils.isNotEmpty(node.getChildList())) {

this.sortNodeList(node.getChildList());

}

}

}

}

/**

* 构建树

*

* @param list

* @return

*/

public Tree build(List list) {

List nodeList = this.initNodeList(list);

List buildNodeList = this.buildNodeStructure(nodeList);

this.sortNodeList(buildNodeList);

Tree tree = new Tree();

tree.setNodeList(buildNodeList);

return tree;

}

}

4.8 Easyui节点实例

实例继承自“节点实例NodeInstance”,此类实例可根据实际要求自行定义和扩展。

package com.sa.example.tree.ext;

import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;

import com.sa.example.tree.Node;

import com.sa.example.tree.NodeInstance;

import org.apache.commons.collections4.CollectionUtils;

import org.apache.commons.collections4.MapUtils;

import org.apache.commons.lang3.StringUtils;

import java.util.List;

import java.util.Map;

/**

* Easyui节点实例

*/

public class EasyuiNode extends NodeInstance {

@Override

public JSONObject toJson() {

JSONObject jsonObject = new JSONObject();

// ==========【(1)组装必有属性】==========

jsonObject.put("id", this.getCode());

jsonObject.put("text", this.getName());

// ==========【(2)组装可选属性】==========

String css = this.getCss();

if (StringUtils.isNotEmpty(css)) {

jsonObject.put("iconCls", css);

}

String state = this.getState();

if (StringUtils.isNotEmpty(state)) {

jsonObject.put("state", state);

}

Boolean checked = this.getChecked();

if (checked != null) {

jsonObject.put("checked", checked);

}

Map extMap = this.getExtMap();

if (MapUtils.isNotEmpty(extMap)) {

JSONObject attributesObject = new JSONObject();

for (Map.Entry entry : extMap.entrySet()) {

attributesObject.put(entry.getKey(), entry.getValue());

}

jsonObject.put("attributes", attributesObject);

}

// ==========【(3)组装子节点】==========

List childList = this.getChildList();

if (CollectionUtils.isNotEmpty(childList)) {

JSONArray jsonArray = new JSONArray();

for (Node child : childList) {

jsonArray.add(child.toJson());

}

jsonObject.put("children", jsonArray);

}

return jsonObject;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值