集合中的多列求和
前言
- 最近公司做项目需要对集合中的很多字段进行求和操作,很多是多少70多个吧.
代码实现
-
求和工具类 public class NumberUtil {
public static <T extends Number> T add(List<T> numbs) {
if (numbs == null || numbs.isEmpty()) {
return null;
}
Class<? extends Number> aClass = numbs.get(0).getClass();
if (isBaseTypePackaging(aClass) || aClass.isPrimitive()) {
Integer sumInteger = 0;
Long sumLong = 0L;
BigDecimal bigDecimal = new BigDecimal("0.0");
for (T numb : numbs) {
if (numb == null) {
continue;
}
if (aClass.isAssignableFrom(Integer.class)) {
sumInteger += numb.intValue();
} else if (aClass.isAssignableFrom(Long.class)) {
sumLong += numb.longValue();
}
}
if (aClass.isAssignableFrom(Integer.class)) {
return (T) sumInteger;
} else if (aClass.isAssignableFrom(Long.class)) {
return (T) sumLong;
}
return null;
} else if (aClass.isAssignableFrom(BigDecimal.class)) {
BigDecimal count = new BigDecimal("0.00");
for (T numb : numbs) {
if (numb == null) {
continue;
}
BigDecimal num = (BigDecimal) numb;
count = count.add(num);
}
return (T) count;
}
return null;
}
private static boolean isBaseTypePackaging(Class c) {
return c.equals(java.lang.Integer.class) || c.equals(java.lang.Byte.class) || c.equals(java.lang.Long.class) || c.equals(java.lang.Double.class) || c.equals(java.lang.Float.class) || c.equals(java.lang.Character.class) || c.equals(java.lang.Short.class) || c.equals(java.lang.Boolean.class);
}
}
-
注解 @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SumIgnore {
}
-
反射实现类 public class SumUtilPro {
private static final Set<String> calTypeSet = new HashSet<>(Arrays.asList("Integer","Long","BigDecimal"));
public static <T, E extends Number> T mapperSum(List<T> list, Class<T> clazz) throws Exception {
T obj = clazz.newInstance();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
SumIgnore sumIgnore = declaredField.getAnnotation(SumIgnore.class);
if (sumIgnore != null) {
continue;
}
Class<?> filedType = declaredField.getType();
String fileSampleName = filedType.getSimpleName();
if (!calTypeSet.contains(fileSampleName)) {
continue;
}
String fieldName = firstLetterToUpper(declaredField.getName());
Method method = clazz.getMethod("get" + fieldName);
List<E> data = new ArrayList<>();
for (T t : list) {
E e = (E) method.invoke(t);
if (ObjectUtil.isNotNull(e)) {
data.add(e);
}
}
if (ObjectUtil.isEmpty(data)) {
continue;
}
E add = NumberUtil.add(data);
String setMethodName = "set" + fieldName;
Method setMethod = clazz.getMethod(setMethodName, filedType);
setMethod.invoke(obj, add);
}
return handleNull(obj);
}
private static String firstLetterToUpper(String str) {
char[] array = str.toCharArray();
array[0] -= 32;
return String.valueOf(array);
}
public static <T> T handleNull(T o) throws Exception {
Class<? extends Object> cls = o.getClass();
Field[] fields = cls.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
f.setAccessible(true);
System.out.println("属性名:" + f.getName() + ";属性值:" + f.get(o) + ";字段类型:" + f.getType());
if (f.get(o) == null) {
String fileTypeName = f.getType().getSimpleName();
switch (fileTypeName) {
case "String":
f.set(o, "");
break;
case "Long":
f.set(o, 0l);
break;
case "Integer":
f.set(o, 0);
break;
case "BigDecimal":
f.set(o, new BigDecimal("0.00"));
break;
default:
f.set(o, 0.00);
break;
}
}
}
return o;
}
}
|