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 实现大批量数据的分组统计
猜你喜欢
转载自ahua186186.iteye.com/blog/2264972
今日推荐
周排行