`
xingqiliudehuanghun
  • 浏览: 7293 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

发个行转列的代码,顺便了解下大家是如何进行行转列

阅读更多
package com.saturday;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 一个行转列的小程序,将如下结构的数据:
 *    c1,c2,pk,fk1,v1
 *    c1,c2,pk,fk2,v2
 *    c1,c2,pk,fk3,v3
 *    .....
 *  转化为:
 *    c1,c2,pk,v1,v2,v3.....
 *    
 * @author 王建波
 *
 */
public class Record2Horrizen {
	public static void main(String[] args){
		List<Map> records=getRecords(
						DataGetter.getData(),
						"id",
						"course",
						"grade"
					);
		String sTemplete=" ID:%1$-10s"
		                +"姓名:%2$-10s"
        				+"语文:%3$-10s"
        				+"数学:%4$-10s"	
        				+"英语:%5$-10s"	
        				+"物理:%6$-10s";
        				
		for(Map record:records){
			System.out.println(String.format(
				sTemplete,
				record.get("id"),
				record.get("name"),
				record.get("语文")!=null?record.get("语文"):"--",
				record.get("数学")!=null?record.get("数学"):"--",
				record.get("英语")!=null?record.get("英语"):"--",
				record.get("物理")!=null	?record.get("物理"):"--"			
			));
		}
	}
	
	
	/**
	 * 获取行专列后的列表
	 * @param list 原始数据列表(需要提前按主键排序)
	 * @param sPKF 主键字段名称
	 * @param sFKF 外键字段名称
	 * @param sFVF 值字段名称
	 * @return
	 */
	public static List<Map> getRecords(List<Map> list,
									   String sPKF,
									   String sFKF,
									   String sVF){
		List<Map> results=new ArrayList<Map>();		
		
		if(list instanceof List&&list.size()>0){
			Map record,preRecord,rowDataCatch=new HashMap();
			Set<String> colSet=getColSet(list,sFKF,sVF);
			Object pk=list.get(0).get(sPKF);
			
			for(int i=0,len=list.size();i<len;i++){
				record=list.get(i);
				
				//当主键发生跳变或最后一条记录时,行转列输出
				if(i==len-1||!record.get(sPKF).equals(pk)){					
					/*
					 * 若最后一行触发的输出,提前写入缓存。因为写缓存
					 * 操作发生在判断之后,若不这样最后一条数据会被漏掉
					*/
					if(i==len-1){
						rowDataCatch.put(
							record.get(sFKF),
							record.get(sVF)
						);						
					}					
					preRecord=list.get(i-1);
					preRecord.remove(sFKF);
					preRecord.remove(sVF);					
					preRecord.putAll(rowDataCatch);
					
					addRecord(results,colSet,preRecord);
					
					//重新设置主键标记和行数据缓存
					rowDataCatch.clear();
					pk=record.get(sPKF);
				}
				
				//将外键值值字段写入行数据缓存
				if(i<len-1){
					rowDataCatch.put(
						record.get(sFKF),
						record.get(sVF)
					);
				}	
			}
		}
		
		return results;
	}
	
	/**
	 * 统计所有输出列
	 * @param list 数据列表
	 * @param sFKF 外键字段名称
	 * @param sVF  值字段名称
	 * @return
	 */
	private static Set<String> getColSet(List<Map> list,
									    String sFKF,
									    String sVF){
		
		Set<String> colSet=new HashSet<String>();
		
		if(list instanceof List&&list.size()>0){
			Map record=list.get(0);
			
			//非变化字段集合
			for(Object key:record.keySet()){
				if(!key.equals(sFKF)&&!key.equals(sVF))
					colSet.add(key.toString());
			}
			
			//变化字段集合
			for(Map item:list){
				colSet.add((String)item.get(sFKF));
			}
		}		
		
		return colSet;
	}
	
	/**
	 * 将行数据进行列补齐操作后写入输出列表
	 * @param list
	 * @param colSet
	 * @param rowData
	 */
	private static void addRecord(List<Map> list,
			                     Set<String> colSet,
			                     Map rowData){		
		//补齐不存在的列
		for(String column:colSet){
			if(!rowData.containsKey(column)){
				rowData.put(column,null);
			}			
		}
		
		list.add(rowData);
	}
}


从数据库读数据比较麻烦,手动添了几条数据
package com.saturday;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DataGetter {
	public static List<Map> getData(){
		List<Map> datas=new ArrayList<Map>();
		Map record;
		
		//记录1
		record=new HashMap();
		record.put("id", "id-1");
		record.put("name","姓名1");
		record.put("course","语文");
		record.put("grade", 30);
		datas.add(record);
		
		record=new HashMap();
		record.put("id", "id-1");
		record.put("name","姓名1");
		record.put("course","数学");
		record.put("grade", 40);
		datas.add(record);	
		
		record=new HashMap();
		record.put("id", "id-1");
		record.put("name","姓名1");
		record.put("course","英语");
		record.put("grade",60);
		datas.add(record);			

		//记录2
		record=new HashMap();
		record.put("id", "id-2");
		record.put("name","姓名2");
		record.put("course","语文");
		record.put("grade", 60);
		datas.add(record);
		
		record=new HashMap();
		record.put("id", "id-2");
		record.put("name","姓名2");
		record.put("course","物理");
		record.put("grade", 80);
		datas.add(record);	
		
		//记录3
		record=new HashMap();
		record.put("id", "id-3");
		record.put("name","姓名3");
		record.put("course","语文");
		record.put("grade", 60);
		datas.add(record);
		
		record=new HashMap();
		record.put("id", "id-3");
		record.put("name","姓名3");
		record.put("course","英语");
		record.put("grade", 80);
		datas.add(record);
		
		return datas;
	}
}


控制台输出:
ID:id-1      姓名:姓名1       语文:30        数学:40        英语:60        物理:--       
ID:id-2      姓名:姓名2       语文:60        数学:--        英语:--        物理:80       
ID:id-3      姓名:姓名3       语文:60        数学:--        英语:80        物理:--            
分享到:
评论
4 楼 folie2006 2009-07-22  
如果把map换成对象之后,又怎么实现呢.
3 楼 抛出异常的爱 2009-07-22  
map(key,value)

key = x作标_y作标
2 楼 xingqiliudehuanghun 2009-07-21  
以前我们也用数据库实现,但很麻烦尤其是换数据库的时候,还要重写
1 楼 Leapiny 2009-07-21  
我行列转换一般在数据库测用sql实现。

相关推荐

    STM32CubeMX用户手册中文版UM1718-翻译版.rar

    顺便说下,这个工具是配带教程的,我这里只是告诉大家有这样个工具可以加速开发,具体设置参考官方教程。 生成后打开文件夹内容如下: 上图的inc 和src文件夹里面是生成的主要代码,其他几个文件夹里面的东西,...

    点阵电子钟制作-电路方案

    这个电子钟的主要元件有4块8*8的单色行列式点阵屏单片机控制器,时钟发生芯片,温度检测芯片和一个BCD转16线的转换芯片。大家也可以根据自己的需要加装蜂鸣器和红外遥控接收头之类的外围接口。这台电子钟最关键的...

    移动电源方案_原理图及源程序.rar

    移动电源方案是一个重要的技术领域,尤其在如今便携式电子设备普及的时代。这个方案涉及到硬件设计、软件编程以及电源管理等多个方面。在这个“移动电源方案_原理图及源程序.rar”压缩包中,包含了实现这一功能所需...

    PHP基础教程 是一个比较有价值的PHP新手教程!

    在许多人的无私奉献下以及这种语言本身的源代码自由性质,它演变成为一种特点丰富的语言,而且现在还在成长中。 PHP虽然很容易学习,但是速度上比mod_perl(植入web服务器的perl模块)慢。现在有了可以与mod_perl...

    LINGO软件的学习

    例1.2 使用LINGO软件计算6个发点8个收点的最小费用运输问题。产销单位运价如下表。 单 位 销地 运 价 产地 B1 B2 B3 B4 B5 B6 B7 B8 产量 A1 6 2 6 7 4 2 5 9 60 A2 4 9 5 3 8 5 8 2 55 A3 5 2 1 9 7 4 3 3 51 A4 7...

    IBM DB2通用数据库SQL入门.pdf

    使用GROUP BY子句可以按指定列对查询结果进行分组,并结合聚合函数进行统计分析。 ##### ZGROUPBYSd.s9CHAVINGS d 这里可能是在讲解**HAVING子句**的使用。HAVING子句用于过滤分组后的结果集,通常与GROUP BY子句...

    programming perl

    **4.4.1 分支(case)结构**:类似于switch-case结构,用于基于多个条件执行不同的代码块。 **4.5 goto** 允许程序执行跳转。 **4.6 全局声明** 全局变量在整个程序中都可访问。 **4.7 范围声明** - **4.7.1 ...

Global site tag (gtag.js) - Google Analytics