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

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 物理:--
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值