import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* BeanUtils
*/
public final class BeanUtils {
/**
* 对list的某个int属性求和
*
* @param list
* @param property 属性get方法
* @param <T>
* @return
*/
public static <T> int sumIntProperty(List<T> list, Function<? super T, Integer> property) {
return list.stream().mapToInt(property::apply).sum();
}
/**
* 对list的某个BigDecimal属性求和
*
* @param list
* @param property 属性get方法
* @param <T>
* @return
*/
public static <T> BigDecimal sumBigDecimalProperty(List<T> list, Function<? super T, BigDecimal> property) {
return list.stream().mapToLong(value -> property.apply(value).longValue()).mapToObj(BigDecimal::valueOf).reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 对list的多个属性求和
*
* @param list
* @param properties 属性名集
* @param <T>
* @return 返回Map
*/
public static <T> Map<String, Object> sumProperties(List<T> list, String... properties) throws NoSuchMethodException {
Map<String, Function<T, Object>> propertyMap = getPropertyFunctionMap(list, properties);
Map<String, Object> result = new HashMap<>();
for (String property : properties) {
if (propertyMap.containsKey(property)) {
Function<T, Object> function = propertyMap.get(property);
Object sum = list.stream().map(function).reduce(null, (a, b) -> {
return getSum(property, a, b);
});
result.put(property, sum);
}
}
return result;
}
/**
* 对list的多个属性求和
*
* @param list
* @param properties 属性名集
* @param <T>
* @return 返回实体对象
*/
public static <T> T sumObjProperties(List<T> list, String... properties) throws NoSuchMethodException {
Map<String, Function<T, Object>> propertyMap = getPropertyFunctionMap(list, properties);
Class clazz = list.get(0).getClass();
T result = (T) createNewInstance(clazz);
for (String property : properties) {
if (propertyMap.containsKey(property)) {
Function<T, Object> function = propertyMap.get(property);
Object sum = list.stream().map(function).reduce(null, (a, b) -> {
return getSum(property, a, b);
});
// 设置求和结果给新对象的对应属性
try {
Method setterMethod =
clazz.getMethod("set" + property.substring(0, 1).toUpperCase() + property.substring(1),
sum.getClass());
setterMethod.invoke(result, sum);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return result;
}
private static Object getSum(String property, Object a, Object b) {
if (a == null) {
return b;
} else if (b == null) {
return a;
} else if (a instanceof Integer) {
return (int) a + (int) b;
} else if (a instanceof BigDecimal) {
return ((BigDecimal) a).add((BigDecimal) b);
} else {
throw new IllegalArgumentException("不支持的属性计算类型:" + property);
}
}
private static <T> Map<String, Function<T, Object>> getPropertyFunctionMap(List<T> list, String[] properties) throws NoSuchMethodException {
Map<String, Function<T, Object>> propertyMap = new HashMap<>();
Class<?> clazz = list.get(0).getClass();
for (String property : properties) {
Method method = clazz.getMethod("get" + property.substring(0, 1).toUpperCase() + property.substring(1));
Class<?> returnType = method.getReturnType();
if (returnType == Integer.class || returnType == int.class) {
propertyMap.put(property, (Function<T, Object>) value -> {
try {
return method.invoke(value);
} catch (Exception e) {
e.printStackTrace();
return null;
}
});
} else if (returnType == BigDecimal.class) {
propertyMap.put(property, (Function<T, Object>) value -> {
try {
return method.invoke(value);
} catch (Exception e) {
e.printStackTrace();
return null;
}
});
} else {
throw new IllegalArgumentException("Unsupported type for " + property);
}
}
return propertyMap;
}
private static <T> T createNewInstance(Class<T> clazz) {
try {
return clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
【Java】对list中多个属性求和
最新推荐文章于 2024-05-10 20:52:01 发布