package com.xxx;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* 使用demo
*
* group(data,new String[]{"code","name"},new String[]{"amount","quantity"},new String[][]{{"amount","avgAmount"},{"quantity","avgQuantity"}},"");
* 以上例子为
* 按code,name分组,sum amount,quantity两个字段 以及计算quantity,amount的平均值生成的对应的字段为avgAmount,avgQuantity
* 需要注意的是 计算平均的字段必须计算合计 即avgFields中的内容必须包函在sumFields中
*
*
* 测试用例
* DataUtils test = new DataUtils();
List<Map<String,Object>> data= new ArrayList<Map<String,Object>>();
Map<String,Object> map = new HashMap<String,Object>();
map.put("code", "001");
map.put("name", "test");
map.put("quantity", "20");
map.put("amount", "100");
map.put("price", "5");
data.add(map);
map = new HashMap<String,Object>();
map.put("code", "001");
map.put("name", "test");
map.put("quantity", "10");
map.put("amount", "200");
map.put("price", "20");
data.add(map);
map = new HashMap<String,Object>();
map.put("code", "002");
map.put("name", "test1");
map.put("quantity", "10");
map.put("amount", "200");
map.put("price", "20");
data.add(map);
map = new HashMap<String,Object>();
map.put("code", "003");
map.put("name", "test1");
map.put("quantity", "10");
map.put("amount", "200");
map.put("price", "20");
data.add(map);
List<Map<String,Object>> result = test.group(data,new String[]{"code","name"},new String[]{"amount","quantity"},new String[][]{{"amount","avgAmount"},{"quantity","avgQuantity"}},"");
* @author 461245
*
*
*/
public class DataUtils {
private String keyValueSplitChar= "=";
private String filedSplitChar= "|";
/**
* 分组函数
*
* @param groupFields
* 分组字段
* @param sumFields
* 合计字段
* @param avgFields
* 平均值字段
* @return
*/
public List<Map<String,Object>> group(List<Map<String,Object>> datas,String[] groupFields,String[] sumFields,String[][] avgFields){
return group(datas,groupFields,sumFields,avgFields,null);
}
/**
* 分组函数
*
* @param groupFields
* 分组字段
* @param sumFields
* 合计字段
* @param avgFields
* 平均值字段
* @param countField
* 分组后的count新字段
* @return
*/
public List<Map<String,Object>> group(List<Map<String,Object>> datas,String[] groupFields,
String[] sumFields,String[][] avgFields,String countField){
Map<String,Object> temp = new HashMap<String,Object>();
for (Map<String,Object> data : datas) {
String groupFieldKey = "";
for (String groupField : groupFields) {
//code_name_ 即 code_001|name_test| code_003|name_test1|
groupFieldKey+=groupField+getKeyValueSplitChar()+data.get(groupField)+getFiledSplitChar();
}
//算分组合计
if(sumFields!=null)
groupSum(sumFields, temp, data, groupFieldKey);
//统计分组行数
if(countField!=null)
countField = groupCount(countField, temp, groupFieldKey);
//计算平均
if(avgFields!=null)
groupAvg(avgFields, countField, temp, groupFieldKey);
}
//转换结果
List<Map<String, Object>> results = covertResult(temp);
return results;
}
private void groupAvg(String[][] avgFields, String countField,
Map<String, Object> temp, String groupFieldKey) {
for (int i = 0; i < avgFields.length; i++) {
for (int j = 0; j < avgFields.length; j++) {
double value = (Double) temp.get(groupFieldKey+avgFields[i][0]);
int count = (Integer) temp.get(groupFieldKey+countField);
temp.put(groupFieldKey+avgFields[i][1], value/count);
}
}
}
/**
* 统计分组后的条数
* @param countField
* @param temp
* @param groupFieldKey
*/
private String groupCount(String countField, Map<String, Object> temp,
String groupFieldKey) {
if(countField == null || countField.trim().equals(""))countField = "&count";
String countFieldKey = groupFieldKey+countField;
if(temp.containsKey(countFieldKey)){
temp.put(countFieldKey, Integer.parseInt(temp.get(countFieldKey).toString())+1);
}else{
temp.put(countFieldKey, 1);
}
return countField;
}
/**
* 将temp中的key value 转换为List<Map<String,Object>>对像
* @param temp
* @return
*/
private List<Map<String, Object>> covertResult(Map<String, Object> temp) {
Map<String,Object> values = new HashMap<String,Object>();
for (String key : temp.keySet()) {
if(!values.containsKey(key.substring(0, key.lastIndexOf(getFiledSplitChar())))){
//code_001|name_test|quantity_10
values.put(key.substring(0, key.lastIndexOf(getFiledSplitChar())), key+getKeyValueSplitChar()+temp.get(key));
continue;
}
for (String rk : values.keySet()) {
if(key.startsWith(rk)){
//code_001|name_test|quantity_10|amount_20
values.put(rk, values.get(rk)+key.substring(key.lastIndexOf(getFiledSplitChar()))+getKeyValueSplitChar()+temp.get(key));
break;
}
}
}
List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
Map<String,Object> result;
for (Object key : values.values()) {
result = new HashMap<String,Object>();
String ss[] = key.toString().split("\\"+getFiledSplitChar());
for (String t : ss) {
String[] ts = t.split("\\"+getKeyValueSplitChar());
result.put(ts[0], ts[1]);
}
results.add(result);
}
return results;
}
/**
* 计算合计
* @param sumFields
* @param temp
* @param data
* @param groupFieldKey
*/
private void groupSum(String[] sumFields, Map<String, Object> temp,
Map<String, Object> data, String groupFieldKey) {
for (String sumField : sumFields) {
String groupFieldKey_sumField = groupFieldKey+sumField;
//code_name_quantity code_name_amount
//即code_001|name_test|quantity code_001|name_test|amount code_003|name_test1|amount
if(temp.containsKey(groupFieldKey_sumField)){
temp.put(groupFieldKey_sumField, Double.parseDouble(data.get(sumField).toString())+Double.parseDouble(temp.get(groupFieldKey_sumField).toString()));
}else{
temp.put(groupFieldKey_sumField, Double.parseDouble(data.get(sumField).toString()));
}
}
}
public static void main(String[] args) {
DataUtils test = new DataUtils();
List<Map<String,Object>> data= new ArrayList<Map<String,Object>>();
Map<String,Object> map = new HashMap<String,Object>();
map.put("code", "001");
map.put("name", "test");
map.put("quantity", "20");
map.put("amount", "100");
map.put("price", "5");
data.add(map);
map = new HashMap<String,Object>();
map.put("code", "001");
map.put("name", "test");
map.put("quantity", "10");
map.put("amount", "200");
map.put("price", "20");
data.add(map);
map = new HashMap<String,Object>();
map.put("code", "002");
map.put("name", "test1");
map.put("quantity", "10");
map.put("amount", "200");
map.put("price", "20");
data.add(map);
map = new HashMap<String,Object>();
map.put("code", "003");
map.put("name", "test1");
map.put("quantity", "10");
map.put("amount", "200");
map.put("price", "20");
data.add(map);
List<Map<String,Object>> result = test.group(data,new String[]{"code","name"},
new String[]{"amount"},null,"");
DataUtils test1 = new DataUtils();
List<Map<String,Object>> result2 = test1.group(data, new String[]{"code","name"}, new String[]{"amount"}, null);
System.out.println(result2);
}
public String getKeyValueSplitChar() {
return keyValueSplitChar;
}
public void setKeyValueSplitChar(String keyValueSplitChar) {
this.keyValueSplitChar = keyValueSplitChar;
}
public String getFiledSplitChar() {
return filedSplitChar;
}
public void setFiledSplitChar(String filedSplitChar) {
this.filedSplitChar = filedSplitChar;
}
}
分享到:
相关推荐
java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制
JAVA使用线程池查询大批量数据
java解决大批量数据导出Excel产生内存溢出的方案
java大批量文件处理
目前java框架中能够生成excel文件的的确不少,但是,能够生成大数据量的excel框架,我倒是没发现,一般数据量大了都会出现内存溢出,所以,生成大数据量的excel文件要返璞归真,用java的基础技术,IO流来实现。...
java实现各种数据统计图,包括柱形图,饼图,折线图,使用jFreeChart
Java实现:月,日,年,周,访问量统计
用Jfree实现条形柱状图表,java代码实现。可经常用于报表的制作,代码自动生成后可以自由查看。可以自由配置图表的各个...本文给大家介绍使用java实现各种数据统计图(柱形图,饼图,折线图),需要的朋友可以参考下
轻松解决普通poi形式导出Excel的中出现的栈溢出问题,此资源可实现千万级数据分批导出csv文件,测试实现16500000条数据大概80秒左右;具体表里内容。
Java向数据库中插入大量数据时的优化
Java数据生成统计图表程序,根据输入的温数据数据生成统计折线图,采用的java数据结构,java swing和java图形.
非常完美Java实现年、月、日、周访问量统计、欢迎jia3456.com大家下载!
附件为mongoDB之Java通过group函数来实现统计和分组的文档描述
主要为大家详细介绍了java导出大批量即百万以上数据的excel文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
内部java实现多个数据库,保持数据同步案例。
Java大批量导出数据EXCEL
Java多线程实现数据切割批量执行,实现限流操作。 java线程池Executors实现数据批量操作。 批量异步Executors处理数据,实现限流操作,QPS限流。 线程池调用第三方接口限流实现逻辑。 案例适合: 1.批量处理大数据。...
主要为大家详细介绍了Java实现excel大数据量导入,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
在java web系统应用中我们经常会用到大批量数据的导出,动辄就上几十万几百万的数据让我们的程序感觉压力很大,甚至都出现无法导出的情况,如内存溢出等。 java中使用poi导出Excel大批量数据到客户端 存在两个导出...