List 无限分类生成树结构

在处理无限树分类中,因为子类中的pid 是重复出现的,所以在获取所有子类的父类时使用了list.contains来判断父类是否已经保存在,如果存在,则不往list中添加,来过滤重复的pid,得到一个唯一的pid列表。为了能正确判断是否存丰父类,重写了AllTree的equals方法。

AllTree实现Comparable接口为了给树排序用,但此处并没有用来排序,感觉这样排序来代码量大,不如在数据表中直接用sql语名根据一定的规则先把所有的树排好序来的简单。

经过测试,总体还算基本满意,能完成我项目 的

package cn.guhai.tree.test;

//树对象
public class AllTree implements Comparable<AllTree> {

	private int  id;

	private String name;

	private int pid;

	@Override
	public String toString() {
		return "AllTree [id=" + id + ", name=" + name + ", pid=" + pid + "]";
	}
	//重写equals方法,过滤重复的父类时使用
	//在使用list.contains()方法会调用此方法比较
	@Override
	public boolean equals(Object obj) {
		AllTree at = (AllTree) obj;

              //业务需要:当前的pid等于传过来的id时,即说明父类对象已经add到了list中
		if(this.pid==at.id){
			return true;
		}
			return false;
	}

	public AllTree() {
		super();
		// TODO Auto-generated constructor stub
	}

	public AllTree(int id, String name, int pid) {
		super();
		this.id = id;
		this.name = name;
		this.pid = pid;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPid() {
		return pid;
	}

	public void setPid(int pid) {
		this.pid = pid;
	}

	@Override
	public int compareTo(AllTree at) {
		return (this.id>at.id)?1:((this.id<at.id)?-1:0);
	}

}
package cn.guhai.tree.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class AllTreeService {
 private List<AllTree> at ;

 @Before
 public void listTree(){
  at= new ArrayList<AllTree>();
  at.add(new AllTree(1,"A父栏目",0));
  at.add(new AllTree(2,"B父栏目",0));
  at.add(new AllTree(4,"A子栏目",1));
  at.add(new AllTree(5,"A子栏目",1));
  at.add(new AllTree(7,"B子栏目",2));
  at.add(new AllTree(8,"B子栏目",2));
  at.add(new AllTree(9,"B子栏目",2));
  at.add(new AllTree(3,"A子栏目",1));
  at.add(new AllTree(6,"A子栏目",1));
  at.add(new AllTree(11,"B9子栏目",9));
  at.add(new AllTree(12,"B9子栏目",9));
  at.add(new AllTree(10,"B9子栏目",9));
  at.add(new AllTree(13,"B2子栏目",2));
  at.add(new AllTree(14,"B2子栏目",2));
  at.add(new AllTree(15,"B2子栏目",2));
  at.add(new AllTree(16,"B2子栏目",2));
 }
 /**
  *
  * @param parentTree 父节点树
  * @param ats  所有的树
  * @param pids  所有树父类 ID
  * @param tree  已经保存的树结构,初始传入时为null
  */
 public List<AllTree> listChildren(AllTree parentTree ,List<AllTree> ats ,List<Integer> pids,List<AllTree> tree){
  if(tree==null){
   tree  = new ArrayList<AllTree>();
  }
  for(AllTree atr :ats){
   if(atr.getPid()!=0){
    if(atr.getPid()==(parentTree.getId())){
     tree.add(atr);
     //如果父类树列表中包含当前树节点
     if(pids.contains(atr.getPid())){
      List<Integer> pbs = pids;
      pbs.remove(Integer.valueOf(atr.getId()));
      //递归再进行处理
      listChildren(atr , ats ,pbs,tree );
     }
    }
   }
  }

  return tree;

 }

 /**
  * 获取所有父类
  * @param ats   所有分类 父和子
  * @return
  */
 public List<AllTree>  listParent(List<AllTree> ats ){
  List<AllTree> ptrees = new ArrayList<AllTree>();
  for(AllTree at :ats){
   if(!ptrees.contains(at)){
    ptrees.add(at);
   }
  }

  return ptrees;

 }

 /**
  * 获取所有父节点的ID值
  * @param ats
  * @return
  */
 private List<Integer> getParentids(List<AllTree> ats) {
  List<Integer> pids = new ArrayList<Integer>();
  for(AllTree a : ats){
    pids.add(a.getId());
  }
  return pids;
 }

 @Test
 public void getTrees(){
  List<AllTree> atree = new ArrayList<AllTree>();
  List<AllTree> ats= listParent( at );

  Iterator<AllTree> atsiter = ats.iterator();
  while (atsiter.hasNext()){
   AllTree aa= atsiter.next();
   List<Integer> pids = getParentids(ats);
   List<AllTree> tree = null;

    tree =  listChildren(aa,at,pids,null);
    if(tree.size()>1){
     tree.add(0,aa);
    }

    atree.addAll(tree);
  }

  System.out.println(atree);

 }

}
时间: 2024-08-29 18:41:30

List 无限分类生成树结构的相关文章

扁平数据根据`parentId`生成树结构

根据每项的parentId,生成具体树形结构的对象. const nest = (items, id = null, link = 'parent_id') => items .filter(item => item[link] === id) .map(item => ({ ...item, children: nest(items, item.id) })); const comments = [ { id: 1, parent_id: null }, { id: 2, parent

php不用递归完成无限分类,从表设计入手完整演示过程

无限分类是什么就不废话了,可以用递归实现,但是递归从数据库取东西用递归效率偏低,如果从表设计入手,就很容易做到网站导航的实现,下面是某论坛导航,如下图 网上无限分类大多不全面,今天我会从设计表开始, 首先我们先做视图界面, <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>白超华-博客园</title> &

递归无限分类笔记

最近项目都上线了每天巩固一下php知识,下面是关于递归无限分类的比较供大家参考! 数据库一个表就可以了,增加一个parendid字段 也就是子级分类 ,排序大家也可以加一下字段. CREATE TABLE `category` (   `id` int(11) NOT NULL,   `name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,   `sort_order` int(11) DEFAULT NULL,   `parendid` int(

无限分类三:递归

第一步,获取全部数据 第二部,写一个子分类的函数 第三,写一个递归循环函数 代码: /** * 查询所有数据 并且缓存 * */ public function authData(){ $res = $this->order('listorder asc')->select(); // 格式化 foreach($res as $k=>$v){ $result[$v['id']] = $v; } Cache::set('auth',$result); return $result; } /

无限分类1

连接上一个 无限分类 一.新建一个商品表 cid对应上面的ID 二. //获取所有的数据 $pdo = new PDO("mysql:host=localhost;dbname=lamp108",'root',''); $pdo->query("set names gbk"); $stmt = $pdo->query("select * from cate2"); $data = $stmt->fetchAll(2); func

TreeView递归绑定无限分类数据

实现一个动态绑定,无限级分类数据时,需要将数据绑定到TreeView控件,分类表的结构是这样的: 字段 类型 Id int ParentId int Name Nvarchar(64) 实现数据绑定: private void ControlsDataBind() { tvCategory.Nodes.Clear(); List<Models.Category> types = CommonNews.Helper.OperateContext.Current.LoadNewsTypes();

无限分类树操作

获取相应分类id的分类树: public static function getCategoryTree($id){ //$model=M('category'); if($id>0){ $obj=self::selectTable('category',array('id'=>$id),true);//$model->where(array('id'=>$id))->find(); if(!is_null($obj)){ $childList=self::selectTab

php基于左右值排序的无限分类算法

PHP无限分类[左右值]算法 <?php /** * 基于左右值排序的无限分类算法 * 数据库结果为 CREATE TABLE om_catagory ( CatagoryID int(10) unsigned NOT NULL auto_increment, Name varchar(50) default '', Lft int(10) unsigned NOT NULL default '0', Rgt int(10) unsigned NOT NULL default '0', PRIM

深度实现session【包括session入库、session机制和session和cookie的使用方法,完善会话机制(在分布式机器中也能使用)】、无限分类的实现

1.session的注意点:@session_start();//这个配置需要注意,session开启中会有影响,所以使用错误抑制符进行限制[并且使用php.ini对session进行自动开启] session_start()前的输出问题:[session信息本身会增加到http头信息,也就是http主体不能在头前]对php.ini中的输出缓存进行配置,out_buffer的配置[注意:开启之后能够保证输出内容在脚本中缓存] [注意](1)脚本中session变量的键只能是字符串类型的[$_SE