实现Comparator接口对List重排序,List实现分页

最近做了一个策划,先简单描述一下,获取一个排行榜,排序依据用户创建文档个数;开始想使用SQL连接查询出一个用户创建的文档个数,而实际操作一条SQL语句无法实现,出于效率考虑,就想到读到内存中处理;由于要分页,不使用SQL语句,就不能Limit,只能对List进行截取;由于是个排行榜,分页不能影响排行,考虑到数据就一百多条,就全部读入内存,通过程序,实现分页,正/倒排序;下面是部分代码

复制代码
View Code
public class DarenServiceImpl implements IDarenService {

//依赖注入service dao 这里省略
//其它方法
@Override
/**
* type = 1正排序;type = -1 到排序
*/
public List<Object[]> originalDaren(int startRow, int size,int count,int type) {
//获取全部名人
List<Map<String,Object>> famouslist = celebrityHallService.getCelebrityListByType(1, 0, 0, count);
List<Object[]> list = new ArrayList<Object[]>();
if(famouslist!=null && famouslist.size()>0){
for(Map<String,Object> map:famouslist){
PsUserBean user = this.userDao.getPsUserById((Long)map.get("user_id"));
if(user==null || user.getUserId()==null)
break;
Object[] obj = new Object[4];
obj[0]=user;
obj[1]=this.productDao.getCelebrityUploadByUserIdNumber(user.getUserId(), -1, 1);//原创文档个数
obj[2]=this.getCateKeywordMap(user.getUserId());
obj[3]=this.feedService.getCountOfFans(user.getUserId());
list.add(obj);
}
}
Collections.sort(list, new CompareOriginal(type));
if((count-startRow)<size){
return list.subList(startRow, count);
}else{
return list.subList(startRow, startRow+size);
}
}

class CompareOriginal implements Comparator<Object[]>{
int order = -1;
public CompareOriginal(int type) {
this.order = type;
}
@Override
public int compare(Object[] o1, Object[] o2) {
Integer num1 = (Integer)o1[1];
Integer num2 = (Integer)o2[1];
int flag=num1.compareTo(num2);
if(flag==0){
flag = ((Integer)o1[3]).compareTo((Integer)o2[3]);
}
return flag*order;
}
}
}
复制代码

下面做一下解释,方法中传入参数是分页的开始行(startRow),每页大小(size),数据总数(count),正/反排序(type);

famouslist将把所有需要数据吃入内存,然后通过一个内部类CompareOriginal实现Comparator接口,

通过Collections.sort(list, new CompareOriginal(type))对List进行重新排序,构造方法可以实现正反排序;这样一个排行榜就出来了

接下来就是分页,由于不是在sql中使用limit,所有就通过list的subList()方法,每页数据满了好取,最主要是最后一页;当所有数据减去开始行小于一页应有数据量时即可说明是最后一页数据,所有可以截取开始行到结尾;

下面是一个可以运行的小例子,实现list正反排序

复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.log4j.Logger;

public class Test {
// private static Logger logger = Logger.getLogger(Test.class);

public static void main(String[] args) {
List<Object[]> list = new ArrayList<Object[]>();
Object[] obj1 = new Object[]{"a",4,6,6};
Object[] obj2 = new Object[]{"a",4,3,6};
Object[] obj3 = new Object[]{"a",4,8,6};
Object[] obj4 = new Object[]{"a",4,8,6};
Object[] obj5 = new Object[]{"a",4,56,6};
Object[] obj6 = new Object[]{"a",4,43,6};
Object[] obj7 = new Object[]{"a",4,66,6};
Object[] obj8 = new Object[]{"a",4,7,6};
Object[] obj9 = new Object[]{"a",4,1,6};
list.add(obj1);
list.add(obj2);
list.add(obj3);
list.add(obj4);
list.add(obj5);
list.add(obj6);
list.add(obj7);
list.add(obj8);
list.add(obj9);
Collections.sort(list, (new Test()).new CompareOriginal(-1));
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i).clone()[2]);
}
}

class CompareOriginal implements Comparator<Object[]>{
int type;
public CompareOriginal(int num) {
this.type = num;
}
public int compare(Object[] o1, Object[] o2) {
Integer num1 = (Integer)o1[2];
Integer num2 = (Integer)o2[2];
int flag=num1.compareTo(num2);
if(flag==0){
flag = ((Integer)o1[3]).compareTo((Integer)o2[3]);
}
return flag*type;
}
}
}
复制代码




posted on   似非而是  阅读(1263)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

< 2011年12月 >
27 28 29 30 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
1 2 3 4 5 6 7
点击右上角即可分享
微信分享提示