コード例 #1
0
ファイル: TreeUtils.java プロジェクト: jmxcg/BasicPlat
 /**
  * 重组树,根据idc中的结点id,重组forest中的树,新的树包括仅包括idc中所有id结点的所有祖宗结点和子结点
  *
  * @param forest 树对象的列表,此对象是需要重组树的全集
  * @param idc 结点id的Collection
  * @return 重组后的树,此树是原树的一个重组后的拷贝
  * @throws CloneNotSupportedException
  */
 public static <V extends TreeNodeBean> List<TreeNode<V>> restructureTree(
     List<TreeNode<V>> forest, Collection<String> idc) throws CloneNotSupportedException {
   if (forest == null || forest.size() == 0) return null;
   if (idc == null || idc.size() == 0) return null;
   List<TreeNode<V>> restructureForest = new ArrayList<TreeNode<V>>();
   idc = TreeUtils.distinctList(idc);
   for (String id : idc) {
     for (TreeNode<V> tn : forest) {
       TreeNode<V> _ftn =
           tn.getId().equals(id.trim()) ? tn : tn.findNode(id.trim()); // 在原树中查找是否有id结点
       if (_ftn != null) { // 若有
         TreeNode<V> ctn = _ftn.clone(); // 以此id为根的树的克隆
         boolean hasDeal = false;
         for (TreeNode<V> rn : restructureForest) {
           TreeNode<V> _rftn = rn.findNode(ctn.getId());
           hasDeal = (_rftn != null);
         }
         while (!hasDeal) {
           if (!_ftn.isRoot()) _ftn = _ftn.getParent();
           else {
             restructureForest.add(ctn);
             hasDeal = true;
           }
           if (!hasDeal) {
             for (TreeNode<V> rn : restructureForest) { // 查找合适的位置插入
               TreeNode<V> _rftn =
                   rn.getId().equals(_ftn.getId()) ? rn : rn.findNode(_ftn.getId());
               if (_rftn != null) {
                 _rftn.addChild(ctn);
                 hasDeal = true;
               }
             }
           }
           if (!hasDeal) {
             // 造上级结点
             TreeNode<V> _ptn = new TreeNode<V>(_ftn.getTnEntity());
             _ptn.addChild(ctn);
             ctn = _ptn;
           }
         }
       }
     }
   }
   return restructureForest;
 }
コード例 #2
0
ファイル: TreeUtils.java プロジェクト: jmxcg/BasicPlat
 /**
  * 把以"树结点数据Bean"为元素的list转换为树对象
  *
  * @param l 以"树结点数据Bean"为元素的list
  * @return 转换后的对象,是一个Map,有两个元素:<br>
  *     forest——符合id/pid关系的树结点的List,一个森林,实际是以TreeNode为元素的List{List<TreeNode<String>>};符合的标准是,树的根结点的pid="0";
  *     errors——不符合id/pid结构的树结点数据Bean的List,是错误的数据,实际是以TreeNodeBean为元素的List{List<TreeNodeBean>};
  */
 public static Map<String, Object> convertFromList(List<? extends TreeNodeBean> l) {
   Map<String, Object> ret = null;
   if (l != null && l.size() > 0) {
     ret = new HashMap<String, Object>();
     List<TreeNode<TreeNodeBean>> forest = new ArrayList<TreeNode<TreeNodeBean>>();
     List<TreeNodeBean> errors = null;
     int mergeFlag;
     // 第一次对List处理,把List中的元素插入forest;
     for (TreeNodeBean tnb : l) {
       TreeNode<TreeNodeBean> oneNode = new TreeNode<TreeNodeBean>(tnb);
       if (forest.size() == 0) forest.add(oneNode);
       else { // 判断forest中有没有oneNode的子结点或父结点
         mergeFlag = 0;
         for (int i = 0; i < forest.size(); i++) {
           TreeNode<TreeNodeBean> node = forest.get(i);
           if (node.getId().equals(oneNode.getParentId())) { // 判断oneNode是不是某个结点的子结点
             node.addChild(oneNode);
             mergeFlag = 1;
           } else if (node.findNode(oneNode.getParentId()) != null) { // 判断oneNode是不是某个结点的子结点
             node.findNode(oneNode.getParentId()).addChild(oneNode);
             mergeFlag = 1;
           } else if (node.getParentId() != null
               && node.getParentId().equals(oneNode.getId())) { // 判断oneNode是不是某个结点的父结点
             oneNode.addChild(node);
             forest.set(i, oneNode);
             mergeFlag = 2;
           }
           if (mergeFlag != 0) break;
         }
         if (mergeFlag == 0) forest.add(oneNode);
       }
     }
     // 对forest逐个处理
     int _fSize = 0, fSize = forest.size();
     // int n=0;
     while (_fSize != fSize && fSize > 1) {
       fSize = forest.size();
       int index = 0;
       TreeNode<TreeNodeBean> node = forest.get(index); // 标记结点
       while (node != null) {
         int _index = 0;
         TreeNode<TreeNodeBean> _node = forest.get(_index); // 循环结点
         boolean eatNode = false; // 是否吃掉标记结点
         while (_node != null) {
           mergeFlag = -1;
           if (!_node.getId().equals(node.getId())) {
             if (_node.getId().equals(node.getParentId())) { // 循环结点是标记结点的父节点
               _node.addChild(node);
               mergeFlag = 1;
               eatNode = true;
             } else if (_node.findNode(node.getParentId()) != null) { // 循环结点是标记结点的祖宗结点
               _node.findNode(node.getParentId()).addChild(node);
               mergeFlag = 1;
               eatNode = true;
             } else if (_node.getParentId() != null
                 && _node.getParentId().equals(node.getId())) { // 循环结点是标记结点的直接子结点
               node.addChild(_node);
               forest.remove(_index);
               mergeFlag = 2;
             } else if (node.findNode(_node.getParentId()) != null) { // 循环结点是标记结点的后续子结点
               node.findNode(_node.getParentId()).addChild(_node);
               forest.remove(_index);
               mergeFlag = 2;
             }
           }
           if (mergeFlag == 1 || mergeFlag == -1) _index++;
           if (_index > forest.size() - 1) _node = null;
           else _node = forest.get(_index);
         }
         if (eatNode) {
           forest.remove(index);
         } else index++;
         if (index > forest.size() - 1) node = null;
         else node = forest.get(index);
       }
       _fSize = forest.size();
     }
     // System.out.println("=================="+n);
     // 处理完森林,下面从森林中,去除那些错误的结点,这里有一个默认的逻辑,pid=0的是正常的结点,这个在下一个版本修改吧
     for (int i = forest.size() - 1; i >= 0; i--) {
       TreeNode<TreeNodeBean> tn = forest.get(i);
       if (tn.getParentId() != null && !tn.getParentId().trim().equals("0")) {
         if (errors == null) errors = new ArrayList<TreeNodeBean>();
         errors.addAll(forest.remove(i).getAllBeansList());
       }
     }
     ret.put("forest", forest);
     ret.put("errors", errors);
   }
   return ret;
 }