Java集合分组算法

        在实际开发中,可能会遇到这么一种情况:对集合进行分组,这里使用Collection集合。所谓分组,笔者是指对集合中有相同特征的元素进行归纳,用例中使用map表示,将相同特征做为Key,将具有此特征的元素作为一个List的集合存入Value中,废话不多说了,直接上代码:

[ Data.java]

01 package net.yeah.likun_zhang;
02  
03 /**
04  *
05  * @author  ZhangLiKun
06  * @mail    likun_zhang@yeah.net
07  * @date    2013-4-23
08  */
09 public class Data {
10  
11     private Long id ;
12     private Long courseId ;
13     private String content ;
14  
15     public Long getId() {
16         return id;
17     }
18  
19     public Data setId(Long id) {
20         this.id = id;
21         return this ;
22     }
23  
24     public Long getCourseId() {
25         return courseId;
26     }
27  
28     public Data setCourseId(Long courseId) {
29         this.courseId = courseId;
30         return this ;
31     }
32  
33     public String getContent() {
34         return content;
35     }
36  
37     public Data setContent(String content) {
38         this.content = content;
39         return this ;
40     }
41      
42 }

[GroupTest.java]

001 package net.yeah.likun_zhang.example;
002  
003 import java.util.ArrayList;
004 import java.util.Collection;
005 import java.util.HashMap;
006 import java.util.Iterator;
007 import java.util.List;
008 import java.util.Map;
009  
010 import junit.framework.Assert;
011 import net.yeah.likun_zhang.Data;
012  
013 import org.junit.After;
014 import org.junit.Before;
015 import org.junit.Test;
016  
017 /**
018  * 集合分组测试
019  * @author  ZhangLiKun
020  * @mail    likun_zhang@yeah.net
021  * @date    2013-4-23
022  */
023 public class GroupTest {
024  
025     /**
026      * 分組依據接口,用于集合分組時,獲取分組依據
027      * @author  ZhangLiKun
028      * @title   GroupBy
029      * @date    2013-4-23
030      */
031     public interface GroupBy<T> {
032         T groupby(Object obj) ;
033     }  
034      
035     /**
036      *
037      * @param colls
038      * @param gb
039      * @return
040      */
041     public static final <T extends Comparable<T> ,D> Map<T ,List<D>> group(Collection<D> colls ,GroupBy<T> gb){
042         if(colls == null || colls.isEmpty()) {
043             System.out.println("分組集合不能為空!");
044             return null ;
045         }
046         if(gb == null) {
047             System.out.println("分組依據接口不能為Null!");
048             return null ;
049         }
050         Iterator<D> iter = colls.iterator() ;
051         Map<T ,List<D>> map = new HashMap<T, List<D>>() ;
052         while(iter.hasNext()) {
053             D d = iter.next() ;
054             T t = gb.groupby(d) ;
055             if(map.containsKey(t)) {
056                 map.get(t).add(d) ;
057             else {
058                 List<D> list = new ArrayList<D>() ;
059                 list.add(d) ;
060                 map.put(t, list) ;
061             }
062         }
063         return map ;
064     }  
065      
066      
067     @Test
068     public void test() {
069         // 准备一个集合
070         final int loop = 1000 1000 ;
071         List<Data> list = new ArrayList<Data> () ;  // size=8 * loop
072         for(int i = 0 ; i < loop ;i ++) {
073             list.add(new Data().setId(1L).setCourseId(200010L).setContent("AAA")) ;
074             list.add(new Data().setId(2L).setCourseId(200010L).setContent("BBB")) ;
075             list.add(new Data().setId(3L).setCourseId(200011L).setContent("CCC")) ;
076             list.add(new Data().setId(4L).setCourseId(200011L).setContent("DDD")) ;
077             list.add(new Data().setId(5L).setCourseId(200010L).setContent("EEE")) ;
078             list.add(new Data().setId(6L).setCourseId(200011L).setContent("FFF")) ;
079             list.add(new Data().setId(7L).setCourseId(200010L).setContent("GGG")) ;
080             list.add(new Data().setId(8L).setCourseId(200012L).setContent("HHH")) ;
081         }
082          
083         // 进行分组
084         Map<Long ,List<Data>> map = group(list, new GroupBy<Long>() {
085             @Override
086             public Long groupby(Object obj) {
087                 Data d = (Data)obj ;
088                 return d.getCourseId() ;    // 分组依据为课程ID
089             }
090         }) ;
091          
092         Assert.assertEquals(3, map.size()) ;
093         Assert.assertEquals(4*loop, map.get(200010L).size()) ;
094         Assert.assertEquals(3*loop, map.get(200011L).size()) ;
095         Assert.assertEquals(1*loop, map.get(200012L).size()) ;
096         Assert.assertEquals("HHH", map.get(200012L).get(0).getContent()) ;
097          
098         // 长度为8 * 1000 * 1000的集合测试用时:6481毫秒!
099          
100     }
101      
102     private long time ;
103      
104     @Before
105     public void setup() {
106         time = System.currentTimeMillis() ;
107     }
108      
109     @After
110     public void teardown() {
111         System.out.println(String.format("程序执行:%d毫秒!",System.currentTimeMillis() - time));
112     }
113      
114 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值