当前位置:首页 > 开发 > 编程语言 > 算法 > 正文

一种多数据源分页算法

发表于: 2012-09-10   作者:asialee   来源:转载   浏览次数:
摘要:    以前开发一个系统,需要去多个系统去取数据,简单期间,比如a,b,c 三个系统,然后抓取过来,每页显示10条,比如a系统的总记录数是10,b是15,c是8条,起先的时候要去这三个系统去查总记录数,但是翻页的时候,有的时候就不需要去各个系统都取了,比如第一页,只要去a系统取数据就可以了,第二页到b系统取10条记录,第三页是在b系统取5条记录,在c系统取5条记录,第四页去c系统

   以前开发一个系统,需要去多个系统去取数据,简单期间,比如a,b,c 三个系统,然后抓取过来,每页显示10条,比如a系统的总记录数是10,b是15,c是8条,起先的时候要去这三个系统去查总记录数,但是翻页的时候,有的时候就不需要去各个系统都取了,比如第一页,只要去a系统取数据就可以了,第二页到b系统取10条记录,第三页是在b系统取5条记录,在c系统取5条记录,第四页去c系统取3条记录。
   之前在网上找过,但是没有找到,后来就自己写了一个算法,可以完美的解决这个问题,直接上代码吧。

package com.xxx.pc.common.pager;

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

import com.xxx.pc.util.ProcessCenterConstants;

public class PageBeanFactory {
	public final static int PAGE_MAX_SHOW_RECORDS = ProcessCenterConstants.DEFAULT_PAGE_SIZE;
	
	public final static int NO_DATA = -1;
	public final static int NOT_REQ = -2;
	
	public static int[] getPageIndex(int[] maxRecords, int pageNum) {
		// 第一页强制发送请求,用来获取最大值
		if(pageNum == 1){
			return initRets(maxRecords.length);
		}
		
		// 如果页码大于最大页码,则调整为最大页码
		int fixPageNum = fixPageNum(maxRecords,pageNum);
		
		// 第一页强制发送请求,用来获取最大值
		if(fixPageNum == 1){
			return initRets(maxRecords.length);
		}
		
		
		int[] returns = generateRets(maxRecords,fixPageNum);

		// 标记不用发送请求的PageBean
		fixNoDataRets(maxRecords,fixPageNum,returns);
		
		return returns;
	}
	
	private static int[] generateRets(int[] maxRecords, int pageNum){
		int maxPagesLength = maxRecords.length;
		int hasDisplayed = (pageNum - 1) * PAGE_MAX_SHOW_RECORDS;
		
		int[] returns = new int[maxPagesLength];
		
		// 计算从什么地方翻页,并计算从什么地方要借数据
		int i = 0;
		for (; i < maxPagesLength; i++) {
			hasDisplayed -= maxRecords[i];
			if (hasDisplayed < 0) {
				break;
			}
		}
		
		for (int j = 0; j < maxPagesLength; j++) {
			if (j < i) {
				returns[j] = NO_DATA;
			} else if (j == i) {
				returns[j] = maxRecords[j] + hasDisplayed;
			} else {
				returns[j] = 0;
			}
		}
		
		return returns;
	}
	
	private static int fixPageNum(int[] maxPages,int pageNum){
		// 负数处理
		if(pageNum <= 0){
			return 1;
		}
		
		int total = 0;
		for(int totalItem : maxPages){
			total += totalItem;
		}
		
		int maxPage = total / PAGE_MAX_SHOW_RECORDS;
		if(total % PAGE_MAX_SHOW_RECORDS != 0){
			maxPage++; 
		}
		if(pageNum > maxPage){
			pageNum = maxPage;
		}
		return pageNum;
	}
	
	
	private static void fixNoDataRets(int[] maxPages, int pageNum,int[] returns) {
		int maxPagesLength = maxPages.length;
		int shoudDisplayed = pageNum * PAGE_MAX_SHOW_RECORDS;
		
		int total = 0;
		int i = 0;
		for(; i < maxPagesLength; i++){
			total += maxPages[i];
			if(total >= shoudDisplayed){
				break;
			}
		}
		
		for(int j = i + 1; j < maxPagesLength; j++){
			returns[j] = NOT_REQ;
		}
	}
	
	private static int[] initRets(int maxLength){
		int[] returns = new int[maxLength];
		for(int i = 0; i < maxLength; i++){
			returns[i] = 0;
		}
		return returns;
	}
	
	public static List<PageBean> create(int currentPage,int[] totals){
		List<PageBean> pageBeans = new ArrayList<PageBean>();
		
		int[] starts = getPageIndex(totals,currentPage);
		
		for(int startItem : starts){
			PageBean pageBean = new PageBean();
			pageBean.setStartRecords(startItem);
			pageBean.setMaxRecords(PAGE_MAX_SHOW_RECORDS);
			
			pageBeans.add(pageBean);
		}
		
		return pageBeans;
	}
	
}



package com.xxx.pc.common.pager;


import java.util.Map;

public class PageBean implements java.io.Serializable{
	private static final long serialVersionUID = 7233650799588141948L;
	
	private Map<String,Object> parameterMap; //生成分页时所带的参数键值对
    private int startRecords = 0; //当前页数
    private Integer maxRecords = PageBeanFactory.PAGE_MAX_SHOW_RECORDS; //一次查询的最大记录数
    private int recordsCount = -1;
   
    public PageBean() {}
    
	public PageBean(int startRecords, Integer maxRecords) {
		this.startRecords = startRecords;
		this.maxRecords = maxRecords;
	}

	public Map<String, Object> getParameterMap() {
		return parameterMap;
	}
	public void setParameterMap(Map<String, Object> parameterMap) {
		this.parameterMap = parameterMap;
	}
	public int getStartRecords() {
		return startRecords;
	}

	public void setStartRecords(int startRecords) {
		this.startRecords = startRecords;
	}

	public Integer getMaxRecords() {
		return maxRecords;
	}
	public void setMaxRecords(Integer maxRecords) {
		this.maxRecords = maxRecords;
	}

	public int getRecordsCount() {
		return recordsCount;
	}
	public void setRecordsCount(int recordsCount) {
		this.recordsCount = recordsCount;
	}
}




   算法就不仔细讲了,比较大的一个原则是根据当前页,计算前一页应该展示多少条数据,计算每个数据源的起始记录数,一种是一个数据源没有数据了,一个是还不需要发请求。

一种多数据源分页算法

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
一、问题研究的背景和意义 在Web应用程序开发领域,基于AJAX技术的JavaScript树形控件已经被广泛使用
COST(i,j)=min{c(j,v) + COST(i+1,v)}   (v∈Vk+1,<j,v>∈E) COST(3,6) = min{6+COST(4,9)
// j为序号从1开始 outputClassItem : function(j, room, ratePlans) { var html = new Array(); va
// j为序号从1开始 outputClassItem : function(j, room, ratePlans) { var html = new Array(); va
一种多租户系统架构 背景: 去年的时候,因为某些特殊原因,有幸带了一个组,参与了B2B平台的开发。
本来想写字符串匹配算法的,感觉题目太大;又想写个多模式匹配算法的,感觉还是太大;最后,写了个A
AC算法,多模式匹配 - zhoubl668的专栏:远帆,梦之帆! - 博客频道 - CSDN.NET AC算法,多模式匹配
由于PowerPivot的数据是内嵌在EXCEL文件中,这种方式好处就是可以作为离线数据分析(即使源数据不可
多模式匹配在这里指的是在一个字符串中寻找多个模式字符字串的问题。一般来说,给出一个长字符串和
和导师在Computers & Geosciences上发表的关于多流向算法GPU并行化的文章(SCI, IF=1.834)。 论文:h
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号