昨天,做项目的时候遇到需要这样将list 分组的 功能,找百度,试了很多方法,一直没有好的方法,再说功能不够强大,只是单纯的一个两个字段group by。心烦,搞到也不想再找了,然后花了两三个小时,整合了一个 List<T> 的 group by 方法,提供了两个重载,一个是只group by,另一个可以count 合并列(Integer,Long,Double,Float)是相加,String 就拼接起来。废话少说,上代码。缺包的看 import ,然后自己下载。
===========================我======是======分======割======线=========================================================
使用方法:
原list<T> lists :
[{"functiontype":23,"identifying":20,"remark":"分页大小10","systemid":0,"value":"10"},{"functiontype":23,"identifying":20,"remark":"分页大小20","systemid":0,"value":"20"},{"functiontype":23,"identifying":20,"remark":"分页大小30","systemid":0,"value":"30"},{"functiontype":23,"identifying":20,"remark":"分页大小40","systemid":0,"value":"40"},{"functiontype":23,"identifying":20,"remark":"分页大小50","systemid":0,"value":"50"},{"functiontype":24,"identifying":21,"remark":"预期5周","systemid":0,"value":"5"}]
===========================我======是======分======割======线=========================================================
调用只group by 方法:
List<SystemInstall> liSystemInstalls = systemListUtil.getListByGroup(
lists,
new String[]{"Functiontype","Identifying"});
数据如下:
[{"functiontype":23,"identifying":20,"remark":"分页大小10","systemid":0,"value":"10"},{"functiontype":24,"identifying":21,"remark":"预期5周","systemid":0,"value":"5"}]
===========================我======是======分======割======线=========================================================
需要合并count的:
List<SystemInstall> liSystemInstalls1 = systemListUtil.getListByGroup(SystemInstall.class,
lists,
new String[]{"Functiontype","Identifying"},new String[]{"Functiontype","Identifying","Value"});
得到数据如下:
[{"functiontype":115,"identifying":100,"remark":"分页大小10","systemid":0,"value":"50,40,30,20,10"},{"functiontype":24,"identifying":21,"remark":"预期5周","systemid":0,"value":"5"}]
===========================我======是======分======割======线=========================================================
其中参数为 string[] 的都是对应字段的 get 、set 方法名字,但是不需要前面的’get‘和‘set’ !!!
代码:
package com.zsm.core.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@SuppressWarnings("unchecked")
public class ListUtil<T extends Serializable> {
/**
* 获得对象属性的值 get 方法
*/
private static Object invokeMethod(Object owner, String methodName) throws Exception {
Class ownerClass = owner.getClass();
Method method = null;
try {
method = ownerClass.getMethod(methodName);
} catch (SecurityException e) { }
catch (NoSuchMethodException e) {
return " can't find 'get" + methodName + "' method";
}
return method.invoke(owner);
}
/**
* @param MethodName
* @param o 调用此方法的对象
* @param paras 调用的这个方法的参数参数列表
*/
private void invokeMethod(String MethodName,Object o,Object []paras){
Class c[]=null;
if(paras!=null){//存在
int len=paras.length;
c = new Class[len];
for(int i=0;i<len;++i){
c[i]=paras[i].getClass();
}
}
try {
Method method=o.getClass().getDeclaredMethod(MethodName,c);
try {
method.invoke(o,paras);//调用o对象的方法
} catch (IllegalAccessException ex) {
Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (NoSuchMethodException ex) {
Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* 该类 使用的 set 方法
*/
private void setMethod(String MethodName,Object o,Object []paras){
invokeMethod("set" + MethodName,o,paras);
}
/**
* 该类 使用的 get 方法
* @throws Exception
*/
private Object getMethod(Object owner, String methodName) throws Exception{
return invokeMethod(owner,"get" + methodName);
}
/**
* List<T> group by 分组
* @list 分组 list
* @groupMethodNames 需要分组的 字段的 get 方法名字
* */
public List<T> getListByGroup(List<T> list,String[] groupMethodNames) throws Exception {
List<T> result = new ArrayList<T>();
for (T bean : list) {
if (!iscontains(bean,result,groupMethodNames)) {
result.add(bean);
}
}
return result;
}
/**
* List<T> group by 分组
* @class1 需要分组的对象 的 class
* @list 分组 list
* @groupMethodNames 需要分组的 字段的 get 方法名字(不需要‘get’)
* @countMethodNames 需要分组后合并的 set 方法名字(不需要‘set’)
* @return boolean
* */
public List<T> getListByGroup(Class<T> class1,List<T> list,String[] groupMethodNames,String[] countMethodNames) throws Exception {
List<T> originalList = new ArrayList<T>();
List<T> result = new ArrayList<T>();
Object objcount;
Object objoriginal;
T originalT;
for (T bean : list) {
if (iscontains(bean,originalList,groupMethodNames)) {
int index = isindexOf(bean,originalList,groupMethodNames);
for (int i = 0; i < countMethodNames.length; i++) {
objcount = getMethod(bean,countMethodNames[i]);//获取 需要合并的 数据
objoriginal = getMethod(result.get(index),countMethodNames[i]);//获取 原来 需要合并的 数据
if (objcount instanceof Integer || objcount instanceof Double || objcount instanceof Float || objcount instanceof Long) {
objcount = ((Integer) objcount).intValue()+((Integer) objoriginal).intValue();
} else if (objcount instanceof String) {
objcount = ((String) objcount)+","+((String) objoriginal);
}
//调用 set 方法 累计 count
setMethod(countMethodNames[i], result.get(index), new Object[]{objcount});
}
} else {
originalT = myclone(bean);
originalList.add(originalT);
result.add(bean);
}
}
return result;
}
/**
* 判断是list 是否存在 与 obj 相同的 对象
* @obj 对比对象
* @elementData 判断的 list 对象
* @groupMethodNames group by 分组字段的 get 方法名(不需要‘get’)
* @return boolean
* */
private boolean iscontains(Object obj,List<T> elementData,String[] groupMethodNames) throws Exception {
return isindexOf(obj, elementData,groupMethodNames) >= 0;
}
/**
* 获取 相同值的 第一个 index
* @obj 对比对象
* @elementData 判断的 list 对象
* @groupMethodNames group by 分组字段的 get 方法名(不需要‘get’)
* @return int
* */
private int isindexOf(Object obj,List<T> elementData,String[] groupMethodNames) throws Exception {
if (obj == null) {
for (int i = 0; i < elementData.size(); i++)
if (elementData.get(i)==null)
return i;
} else {
for (int i = 0; i < elementData.size(); i++)
if (isequals(obj,elementData.get(i),groupMethodNames))
return i;
}
return -1;
}
/**
* 判断 两个值 相等
* @obj1 对比对象1
* @obj2 对比对象2
* @groupMethodNames group by 分组字段的 get 方法名(不需要‘get’)
* @return boolean
* */
private boolean isequals(Object obj1,Object obj2,String[] groupMethodNames) throws Exception {
String str1 = "";
String str2 = "";
for (int i = 0; i < groupMethodNames.length; i++) {
str1 = getMethod(obj1,groupMethodNames[i]).toString();
str2 = getMethod(obj2,groupMethodNames[i]).toString();
if(!str1.equals(str2)){
return false;
}
}
return true;
}
/**
* Discription:[深度复制方法,需要对象及对象所有的对象属性都实现序列化]
* @c 需要复制的对象
* @return 复制后的对象
* */
public T myclone(T c) {
T outer = null;
try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(c);
// 将流序列化成对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
outer = (T) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return outer;
}
}