论坛首页 Java企业应用论坛

递归算法查询无级树形结构下任意分类及其子分类下所有新闻

浏览 8645 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-08-19  
想到用递归算法来实现无级树形分类下任意分类及其子分类下的所有新闻:

java 代码
 
  1. package com.lingirl.test;  
  2.   
  3. import java.util.*;  
  4.   
  5. /** 
  6.  * @author lingirl 
  7.  * 2007-08-19 
  8.  */  
  9. public class Category {  
  10.       
  11.     private Long id;  
  12.     private Category p_category;  
  13.     private String name;  
  14.     private Set children;  
  15.     private Set news;
  16.   
  17. }  

java 代码
 
  1. package com.lingirl.test;  
  2.   
  3. /** 
  4.  * @author lingirl 
  5.  * 2007-08-19 
  6.  */  
  7.   
  8. public class News {  
  9.     private Long id;  
  10.     private String name;  
  11.     private Category category;  
  12.   
  13. }  

java 代码
 
  1. package com.lingirl.test;  
  2.   
  3. import java.util.*;  
  4.   
  5. /** 
  6.  * @author lingirl 
  7.  * 2007-08-19 
  8.  */  
  9.   
  10. public class Treetest {  
  11.     //递归算法求出任意树形分类节点及其所有子类下的所有新闻  
  12.     public Set getAllnews(Category category){  
  13.         if(category.getChildren()!=null)  
  14.         {  
  15.             Iterator chr=category.getChildren().iterator();  
  16.               
  17.             while(chr.hasNext()){  
  18.                  category.getNews().addAll(getAllnews((Category)chr.next()));  
  19.             }  
  20.               
  21.         }  
  22.         return category.getNews();  
  23.     }  
  24.       
  25.   
  26.     /** 
  27.      * @param args 
  28.      */  
  29.     public static void main(String[] args) {  
  30.         // TODO 自动生成方法存根  
  31.         /**假设有一树形分类: 
  32.          * 01 
  33.          *   0101 
  34.          *   0102 
  35.          *       010201 
  36.          * 初始化如下:       
  37.          */  
  38.             Category c01=new Category();  
  39.             c01.setName("01");  
  40.           
  41.             Category c0101=new Category();  
  42.             c0101.setName("0101");  
  43.             //c0101.setP_category(c01);  
  44.             Category c0102=new Category();  
  45.             c0102.setName("0102");  
  46.             //c0102.setP_category(c01);  
  47.               
  48.             Set categories=new HashSet();  
  49.             categories.add(c0101);  
  50.             categories.add(c0102);  
  51.             c01.setChildren(categories);  
  52.               
  53.             Category c010201=new Category();  
  54.             c010201.setName("010201");  
  55.             //c010201.setP_category(c0102);  
  56.             Set categories2=new HashSet();  
  57.               
  58.             categories2.add(c010201);  
  59.             c0102.setChildren(categories2);  
  60.               
  61.             News n1=new News();  
  62.             n1.setName("n1");  
  63.             News n2=new News();  
  64.             n2.setName("n2");  
  65.               
  66.             News n3=new News();  
  67.             n3.setName("n3");  
  68.             News n4=new News();  
  69.             n4.setName("n4");  
  70.             News n5=new News();  
  71.             n5.setName("n5");  
  72.             News n6=new News();  
  73.             n6.setName("n6");  
  74.               
  75.             //c01下有新闻:n1  
  76.             Set news1=new HashSet();  
  77.             news1.add(n1);  
  78.             c01.setNews(news1);  
  79.               
  80.             //c0101下有新闻:n2  
  81.             Set news2=new HashSet();  
  82.             news2.add(n2);  
  83.             c0101.setNews(news2);  
  84.               
  85.             //c0102下有新闻:n3,n4  
  86.             Set news3=new HashSet();  
  87.             news3.add(n3);  
  88.             news3.add(n4);  
  89.             c0102.setNews(news3);  
  90.               
  91.             //c010201下有新闻:n5,n6  
  92.             Set news4=new HashSet();  
  93.             news4.add(n5);  
  94.             news4.add(n6);  
  95.             c010201.setNews(news4);  
  96.               
  97.         Treetest test=new Treetest();  
  98.         Set news=test.getAllnews(c010201);//递归查询出分类c010201及其所有子分类下所有新闻;  
  99.         System.out.println(news.size());  
  100.         Iterator s=news.iterator();  
  101.         while(s.hasNext()){  
  102.             News n=(News)s.next();  
  103.             System.out.println(n.getName());  
  104.             }  
  105.         }  
  106.   
  107. }  

这时查询的是分类c010201,结果打印为:
2
n5
n6

假如查询分类c0102,结果将包含子分类c010201的新闻,结果为:
4
n3
n4
n5
n6

不知道有没有可能通过一句SQL就能实现?先谢谢大家了
   发表时间:2007-08-19  
看看这样行不行.将分类的数据结构变动一下.
public class Category {   
       
    private String id;   
    private Category p_category;   
    private String name;   
    private Set children;   
    private Set news;

   
} 

id的格式如下:001,001001,001002,002,002001等.
这样的话要查询子孙节点的数据不就可以用
from news where category.id like '001%'
0 请登录后投票
   发表时间:2007-08-19  
szjiang 写道
看看这样行不行.将分类的数据结构变动一下.
public class Category {   
       
    private String id;   
    private Category p_category;   
    private String name;   
    private Set children;   
    private Set news;

   
} 

id的格式如下:001,001001,001002,002,002001等.
这样的话要查询子孙节点的数据不就可以用
from news where category.id like '001%'


如果用这种,不如彻底一点。使用 string 类型,需要用 like 来实现查询。不如直接使用 int 作为 id ,整数中的不同 bit 作为不同级别的 id 。详细的做法可以参考
http://www.web745.com/article/303.html
0 请登录后投票
   发表时间:2007-08-21  
彻底一点似乎不错,但保存和修改节点的时候,操作都挺复杂的。不知道两者之间的效率相差多少,如果相差不多,是不是可以使用字符串更简单一些呢?
0 请登录后投票
   发表时间:2007-08-22  
szjiang 写道
看看这样行不行.将分类的数据结构变动一下.
public class Category {   
       
    private String id;   
    private Category p_category;   
    private String name;   
    private Set children;   
    private Set news;

   
} 

id的格式如下:001,001001,001002,002,002001等.
这样的话要查询子孙节点的数据不就可以用
from news where category.id like '001%'


这样编码结构确实清晰,也比较容易实现,而我最担心的是使用字符串做模糊查询,是否会影响效率呢?
0 请登录后投票
   发表时间:2007-08-22  
iunknown 写道


如果用这种,不如彻底一点。使用 string 类型,需要用 like 来实现查询。不如直接使用 int 作为 id ,整数中的不同 bit 作为不同级别的 id 。详细的做法可以参考
http://www.web745.com/article/303.html


根据iunknown提供的资料,尝试采取了这样的做法:ID字段保持不变,在分类里增加一个字段code bigint,最大值是2的64次方,分为8个深度级别的话,每一级可以包括256个项目。

把编码转换成2进制,前8位是第一级,与字符串型编码类似,用16进制来显示的话,01 00 00 00 00 00 00 00是第一级别。01 01 00 00 00 00 00 00是上一个分类的下级分类。下级的最高位都是相同的,因此如果我们希望取得某一分类极其所有子类下的所有新闻,可以使用from News where newsCategory.code>=01 00 00 00 00 00 00 00 and newsCategory.code<02 00 00 00 00 00 00 00。(不知道这样做是否跟iunknown所说到的方法一致?)

但现在对位运算编码和字符串编码的选择有很大疑惑,似乎字符串的更简单,而位运算相对就复杂了点。是否位运算与字符串比较,更有效率呢?
0 请登录后投票
   发表时间:2007-08-22  
> 是否位运算与字符串比较,更有效率呢?

TEST it!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics