Java converts a DataTable data type to a tree structure (multi-fork tree)

Source: Internet
Author: User

Problem analysis: A table of relational databases:


You can see the next four fields: Country,province,city,street has a logical subordinate structure, and now you want to make this data into a tree structure:


Not the original data conversion, roughly this meaning, you can imagine that the same data in the DataTable to merge cells, and then find all the path from the root to the leaf node, even if the task is completed. JS inside seems to have a lot of plug-ins can be implemented, but in Java I have not found, no way can only write their own. From the structural point of view, it should be a multi-fork multi-level tree structure, so in the conversion must have a certain degree of flexibility, the level of the node must be clear.

First, define a node class that describes the nodes:

public class Node {private string Id;private string Pid;private string text;private map<string, object> NODEVALUE;PR Ivate string Path;public node () {}public node (String id,string pid,string text,string path) {this.id = Id;this.pid = pid;th Is.text = Text;this.path = path;} Public String GetId () {return ID;} public void SetId (String id) {this.id = ID;} Public String Getpid () {return pId;} public void Setpid (String pid) {this.pid = pId;} Public String GetText () {return text;} public void SetText (String text) {this.text = text;} Public map<string, Object> Getnodevalue () {return nodevalue;} public void setNodeValue (map<string, object> nodevalue) {this.nodevalue = NodeValue;} Public String GetPath () {return path;} public void SetPath (String path) {this.path = path;} @Overridepublic string toString () {String str = ""; if (this.nodevalue!=null) {set<entry<string,object>> EntrySet = This.nodeValue.entrySet (); for (entry<string, object> entry:entryset) {Str+=entry.getkey () +"=" +entry.getvalue ();}} return str;}}

A brief description of the original design:

1,id and PID will not say, discerning eye one eye to see through. Text indicates what the node is currently displaying.

2,nodevalue is the map structure that contains the text from the current node to the root node, such as: What is the nodevalue of the level three node City=qingdao contains? Answer: {City=qingdao,province=shandong,country=china}

The 3,path property represents the address of a node, or a path, used to identify whether a node already exists, and a style example:/china/shandong/qingdao

See the specific implementation class:

public class Multitree {private list<node> nodelist;private Node rootnode;public list<node> getnodelist () { return nodeList;} public void Setnodelist (list<node> nodeList) {this.nodelist = nodeList;} Public Multitree () {init ();} Public Multitree (list<node> nodeList, Node rootNode) {this (); if (nodeList! = null) {this.nodelist = nodeList;} if (RootNode! = null) {This.rootnode = RootNode;}} private void Init () {nodeList = new arraylist<node> (); rootNode = new Node ("0", "1", "0", "/");} /** * Convert DataTable data to Datatree, guaranteed path Unique * @param listmaps * @param args */public void Convertlistmaptotree (list<map< String, object>> listmaps,string ... args) {Object value = null; String path = ""; Node pnode = null; node node = null; map<string, object> nodevalue = new hashmap<string, object> (); Nodelist.add (RootNode); for (Map<string,  Object> map:listmaps) {path = "";p node = Getroot (); for (int i = 0;i < args.length;i++) {String key = Args[i];value = Map.geT (key);p ath + = "/" + Value;node = Findnodebypath (path), if (node = = null) {node = new node (Idgenerator.uuidgenerator (), PNo De.getid (), string.valueof (value), path), if (i==args.length-1) {nodevalue = map;} Else{nodevalue = Getnodevaluebypath (Path,args);} Node.setnodevalue (NodeValue); nodelist.add (node);} else {pnode = node;}}}} /** * According to node path node should have NodeValue * NodeValue should contain the text of the parent node, and should not contain the text of the child nodes, the leaf node should contain all the values * @param path * @param args * @ret Urn */private map<string, object> getnodevaluebypath (String path, string[] args) {map<string, object> NodeValue = new hashmap<string, object> (); String[] values = Path.split ("/"); for (int i = 1;i < values.length;i++) {nodevalue.put (args[i-1], values[i]);} return nodevalue;} Public Node Getroot () {return rootNode;}  /** * All child nodes of a node * @param pnode * @return */public list<node> getchildnodes (node Pnode) {list<node> ChildNodes = new Arraylist<node> (); if (Pnode = = NULL | | Pnode.getid () = = null) {return childNodes;} for (NoDe Node:nodelist) {if (Pnode.getid (). Equals (Node.getpid ())) {Childnodes.add (node);}} return childNodes;} /** * finds if node exists (because path is unique) * @param path * @return Find node returned by path, otherwise returns null */public node Findnodebypath (String path) {for ( Node Node:nodelist) {if (Path.equals (Node.getpath ())) {return node;}} return null;} /** * Depth recursive traversal starting from a node * @param pnode */public void recursiontraversal (node pnode) {list<node> childNodes = getchildn Odes (Pnode); for (node Node:childnodes) {System.out.println (node.tostring ()); if (Getchildnodes (node). Size () >0) { Recursiontraversal (node);}}}

The core approach to this class is: the Convertlistmaptotree parameter, which is the field name of the data source and node.

Call Mode:

Tree.convertlistmaptotree (Listmaps, "Country", "province", "City", "STREET");

Execution Result:

china/china/hebei/china/hebei/baoding/china/hebei/baoding/street1/china/hebei/hengshui/china/hebei/hengshui/ street1/china/shandong/china/shandong/jian/china/shandong/jian/street1/china/shandong/qingdao/china/shandong/ qingdao/street1/china/shandong/yantai/china/shandong/yantai/street1/japan/japan/jiuzhou/japan/jiuzhou/changqi/ Japan/jiuzhou/changqi/street2/america/america/california/america/california/los Angeles/America/California/Los Angeles/street3/england/england/norwich/england/norwich/any/england/norwich/any/street4


Here are a few points to note:

1, the order in which the field name parameter is passed is the hierarchical order of the nodes, from high to low, if the error is incorrect, the result is inaccurate.

2, must have a root node, which is a necessary tree structure, the program has given the default root node, also gives a custom interface.

3, in this program, NodeValue only contains (except the leaf node) from the current node to the root node of the field values, the leaf node contains all the field values, such as this example, the leaf node also contains id=1 such data, although not applied to the node hierarchy.

4, it is a critical step to determine if the path exists, and if the step is not accurate, the entire program will fail.

Deficiencies:

Many places are looking globally, less efficient, and looking forward to further improvements.

Java converts a DataTable data type to a tree structure (multi-fork tree)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.