stone2083

          基于java實現(xiàn)的多層目錄結(jié)構(gòu)

          最近在做小需求的時候,需要用到目錄樹,特地寫了一個基于java的實現(xiàn)。
          由于需求原因,目前只實現(xiàn)了讀部分的功能--如何將平面節(jié)點build成樹。動態(tài)新增,刪除等功能尚未實現(xiàn)。

          目錄結(jié)構(gòu)概念:


          Node:目錄節(jié)點,具備節(jié)點屬性信息
          NodeStore:平面目錄節(jié)點持久化接口,提供方法如下:
          • public List<T> findByType(String type); -- 根據(jù)目錄類型,獲取該類型下所有的節(jié)點(平面節(jié)點)
          • public void add(T node);--將增加節(jié)點持久化
          • public void update(T node);--將修改節(jié)點持久化
          • public void delete(T node);--刪除節(jié)點
          • public void move(T src, T target); --將移動節(jié)點持久化
          NodeStore是一個接口,可以基于DB實現(xiàn),也可以基于XML實現(xiàn),或則其他你需要的方式。

          Tree:目錄樹,主要職責:
          • 通過NodeStore load某一類型目錄的所有平面節(jié)點,build成樹;
          • 根據(jù)節(jié)點id號,查找相應(yīng)的節(jié)點信息
          • 動態(tài)新增,修改,刪除,移動節(jié)點,通過NodeStore將變化持久化;


          目錄結(jié)構(gòu)實現(xiàn)類圖:(目前只實現(xiàn)了讀方法)


          附上Node,Tree類的核心代碼
          Node.java
            1 public class Node implements Serializable, Comparable<Node> {
            2 
            3     private static final long serialVersionUID = 8085266615416399579L;
            4 
            5     private Integer id; // id號
            6     private Integer parentId;// 父親id號
            7     private String name;// 目錄名
            8     private String description;// 目錄描述
            9     private String type;// 目錄類型
           10 
           11     private Node parent;// 父親
           12     private List<Node> children;// 兒子
           13 
           14     /**
           15      * 添加子節(jié)點,并且建立與當前節(jié)點的父子關(guān)系
           16      * 
           17      * @param child 兒子節(jié)點
           18      */
           19     public void addChild(Node child) {
           20         if (child == null) {
           21             return;
           22         }
           23         // 設(shè)置當前節(jié)點為child的父節(jié)點
           24         child.setParent(this);
           25         // 當前節(jié)點增加child為兒子節(jié)點
           26         if (getChildren() == null) {
           27             setChildren(new ArrayList<Node>());
           28         }
           29         getChildren().add(child);
           30     }
           31 
           32     /**
           33      * 刪除子節(jié)點,并且建立與當前節(jié)點的父子關(guān)系
           34      * 
           35      * @param child 兒子節(jié)點
           36      */
           37     public void removeChild(Node child) {
           38         if (child == null) {
           39             return;
           40         }
           41         // 將child節(jié)點的父節(jié)點清空
           42         child.setParent(null);
           43         if (getChildren() == null) {
           44             return;
           45         }
           46         // 當前節(jié)點刪除child這個兒子節(jié)點
           47         getChildren().remove(child);
           48     }
           49 
           50     /**
           51      * 得到全路徑
           52      * 
           53      * @param sep 分隔符號
           54      * @return
           55      */
           56     public String getPathName(String sep) {
           57         String pathName = getName();
           58         if (getParent() != null) {
           59             pathName = getParent().getPathName(sep) + sep + pathName;
           60         }
           61         return pathName;
           62     }
           63 
           64     /**
           65      * 判斷是否root節(jié)點
           66      * 
           67      * @return
           68      */
           69     public boolean isRootNode() {
           70         return getParentId() == -1;
           71     }
           72 
           73     /**
           74      * 判斷是否是葉子節(jié)點
           75      * 
           76      * @return
           77      */
           78     public boolean isEndNode() {
           79         return getChildren() == null || getChildren().isEmpty();
           80     }
           81 
           82     /**
           83      * 對當前節(jié)點的兒子節(jié)點進行排序
           84      */
           85     public void sortChildren() {
           86         if (isEndNode()) {
           87             return;
           88         }
           89         Collections.sort(getChildren());
           90     }
           91 
           92     /**
           93      * 對當前節(jié)點的所有兒子節(jié)點進行排序
           94      */
           95     public void sortAllChidren() {
           96         if (isEndNode()) {
           97             return;
           98         }
           99         List<Node> children = getChildren();
          100         Collections.sort(children);
          101         for (Node child : children) {
          102             child.sortAllChidren();
          103         }
          104     }
          105 
          106     /**
          107      * 將虛擬目錄轉(zhuǎn)換成JSONObject對象
          108      * <p>
          109      * 本身轉(zhuǎn)換包含id、name兩個屬性,子節(jié)點轉(zhuǎn)換為children屬性的數(shù)組
          110      * </p>
          111      * 
          112      * @return
          113      */
          114     public JSONObject toJson() {
          115         JSONObject jsonObject = new JSONObject();
          116         try {
          117             jsonObject.put("id", id);
          118             jsonObject.put("name", name);
          119             if (!isEndNode()) {
          120                 JSONArray jsonArray = new JSONArray();
          121                 for (Node child : getChildren()) {
          122                     jsonArray.put(child.toJson());
          123                 }
          124                 jsonObject.put("children", jsonArray);
          125             }
          126         } catch (JSONException e) {
          127             // ignore
          128         }
          129         return jsonObject;
          130     }
          131 
          132     @Override
          133     public int compareTo(Node o) {
          134         return this.getId().compareTo(o.getId());
          135     }
          136 
          137 }

          Tree.java:
           1 public class Tree<extends Node> {
           2 
           3     private String type;
           4     private Node root; // root節(jié)點
           5     private Map<Integer, T> nodeHolder = new HashMap<Integer, T>();// 節(jié)點持有器
           6 
           7     private NodeStore<T> nodeStore;
           8 
           9     /**
          10      * 將平面的node list構(gòu)建成樹
          11      * 
          12      * @throws TreeException
          13      */
          14     public void build() throws TreeException {
          15         List<T> nodes = nodeStore.findByType(type);
          16         // 如果nodes為空,則不做任何處理
          17         if (nodes == null || nodes.isEmpty()) {
          18             return;
          19         }
          20         // 設(shè)置root和node持有器
          21         for (T node : nodes) {
          22             if (node.isRootNode()) {
          23                 this.root = node;
          24             }
          25             nodeHolder.put(node.getId(), node);
          26         }
          27 
          28         // 如果root為空,則build失敗了
          29         if (root == null) {
          30             throw new TreeException("no root node found.");
          31         }
          32 
          33         // 建立節(jié)點之前關(guān)系
          34         for (T node : nodes) {
          35             if (node.isRootNode()) {
          36                 continue;
          37             }
          38             Node parent = getNodeById(node.getParentId());
          39             if (parent == null) {
          40                 throw new TreeException("no parent node found.current node id is:" + node.getId());
          41             }
          42             parent.addChild(node);
          43         }
          44 
          45         // 排序
          46         root.sortAllChidren();
          47     }
          48 
          49     /**
          50      * 得到root節(jié)點
          51      * 
          52      * @return
          53      */
          54     public Node getRoot() {
          55         return root;
          56     }
          57 
          58     /**
          59      * 根據(jù)id得到對應(yīng)節(jié)點
          60      * 
          61      * @param id
          62      * @return
          63      */
          64     public Node getNodeById(Integer id) {
          65         return nodeHolder.get(id);
          66     }
          67 
          68     public void setType(String type) {
          69         this.type = type;
          70     }
          71 
          72     public void setNodeStore(NodeStore nodeStore) {
          73         this.nodeStore = nodeStore;
          74     }
          75 
          76 }


          附上中國省份,城市,地區(qū)信息xml文件
          中國區(qū)域文件
          該文件取之網(wǎng)絡(luò),做了修改。但是還有部分信息是不準確的,切記。


          附上源碼(功能不全)
          tree源碼



          posted on 2009-02-28 21:25 stone2083 閱讀(2535) 評論(3)  編輯  收藏

          Feedback

          # re: 基于java實現(xiàn)的多層目錄結(jié)構(gòu) 2009-03-01 13:53 Java宅男

          太高深了,看不懂~~俺是菜鳥  回復  更多評論   

          # re: 基于java實現(xiàn)的多層目錄結(jié)構(gòu) 2009-03-06 18:52 44you

          好好研究一下去~  回復  更多評論   

          # re: 基于java實現(xiàn)的多層目錄結(jié)構(gòu) 2009-03-07 11:08 stone2083

          其實這玩意,也是臨時之作,有很多不完善的地方。
          主要是提供一個思路,供大家一起討論。  回復  更多評論   


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 普陀区| 绥化市| 鄂托克旗| 墨脱县| 水富县| 申扎县| 上思县| 托克托县| 成都市| 广宗县| 凤台县| 莱阳市| 合川市| 汉中市| 法库县| 密山市| 绍兴县| 扎兰屯市| 旌德县| 达拉特旗| 泽州县| 东丽区| 泸西县| 兴宁市| 靖宇县| 六枝特区| 平山县| 丹巴县| 东乡县| 墨江| 道孚县| 太谷县| 阳西县| 湖州市| 建始县| 庆城县| 上虞市| 周宁县| 防城港市| 长武县| 晋州市|