1、Stream分组后并计算各项之和
import static java.util.Comparator.comparing;
/**
* 分组后并计算各项之和
*/
@Test
public void testGroupByAndSum() {
List<User> users = new ArrayList<>();
Boolean mulFlag = true;
Map<String, List<User>> collect = mulFlag ?
// 多个字段进行分组
users.stream().collect(Collectors.groupingBy(item -> item.getId() + '-' + item.getName())) :
// 单字段进行分组
users.stream().collect(Collectors.groupingBy(User::getName));
List<UserStrings> userStrings = new ArrayList<>();
Map<String, List<UserStrings>> collectStrings = mulFlag ?
// 多个字段进行分组
userStrings.stream().collect(Collectors.groupingBy(item -> item.getId() + '-' + item.getName())) :
// 单字段进行分组
userStrings.stream().collect(Collectors.groupingBy(UserStrings::getName));
List<UserStrings> collectResultStrings = new ArrayList<>();
// 对分组后的集合进行计算各项的总和 String
for (Map.Entry<String, List<UserStrings>> entry : collectStrings.entrySet()) {
// 分组后计算总指标 (此时id、age为String类型)
UserStrings temp1 = MathUtil.mapperSumString(UserStrings.class,
entry.getValue(),
UserStrings::getId,
UserStrings::getAge);
UserStrings user = entry.getValue().get(0);
collectResultStrings.add(temp1);
}
// 对分组后的集合进行计算各项的总和 Double
List<UserDouble> collectResult = new ArrayList<>();
List<UserDouble> userDouble = new ArrayList<>();
Map<String, List<UserDouble>> collectDouble = mulFlag ?
// 多个字段进行分组
userDouble.stream().collect(Collectors.groupingBy(item -> item.getId() + '-' + item.getName())) :
// 单字段进行分组
userDouble.stream().collect(Collectors.groupingBy(UserDouble::getName));
for (Map.Entry<String, List<UserDouble>> entry : collectDouble.entrySet()) {
// 分组后计算 (此时id、age为Double类型)
UserDouble temp2 = MathUtil.mapperSum(UserDouble.class,
entry.getValue(),
UserDouble::getId,
UserDouble::getAge);
UserDouble user = entry.getValue().get(0);
collectResult.add(temp2);
}
// 对集合进行排序
collectResult = collectResult.stream().sorted(comparing(UserDouble::getAge).reversed()).collect(Collectors.toList());
}
2、涉及到的工具类
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class MathUtil {
/**
* 返回字符串转double
*
* @param doubleValue
* @return
*/
public static Double getDouble(String doubleValue) {
return StringUtils.hasText(doubleValue) ? new Double(doubleValue) : 0;
}
public static Double str2Double(String doubleValue) {
return Double.valueOf(doubleValue);
}
/**
* 返回多个字符串转double之和
*
* @param doubleFirstValue
* @param doubleSecondValue
* @param doubleThirdValue
* @return
*/
public static double getDoubleMul(String doubleFirstValue, String doubleSecondValue, String doubleThirdValue) {
return addDouble(str2Double(doubleFirstValue), str2Double(doubleSecondValue), str2Double(doubleThirdValue));
}
/**
* 返回多个字符串转double之和(返回string)
*
* @param doubleFirstValue
* @param doubleSecondValue
* @param doubleThirdValue
* @return
*/
public static String getDoubleMulStr(String doubleFirstValue, String doubleSecondValue, String doubleThirdValue) {
return getDouble2String(addDouble(getDouble(doubleFirstValue), getDouble(doubleSecondValue), getDouble(doubleThirdValue)));
}
public static String getDoubleMulStr(String doubleFirstValue, String doubleSecondValue, String doubleThirdValue, String doubleFourthValue) {
return getDouble2String(addDouble(getDouble(doubleFirstValue), getDouble(doubleSecondValue), getDouble(doubleThirdValue), getDouble(doubleFourthValue)));
}
/**
* 加法运算
*
* @param m1
* @param m2
* @return
*/
public static double addDouble(double m1, double m2, double m3) {
BigDecimal p1 = new BigDecimal(Double.toString(m1));
BigDecimal p2 = new BigDecimal(Double.toString(m2));
BigDecimal p3 = new BigDecimal(Double.toString(m3));
return p1.add(p2).add(p3).doubleValue();
}
/**
* 加法运算
*
* @param m1
* @param m2
* @return
*/
public static double addDouble(double m1, double m2, double m3, double m4) {
BigDecimal p1 = new BigDecimal(Double.toString(m1));
BigDecimal p2 = new BigDecimal(Double.toString(m2));
BigDecimal p3 = new BigDecimal(Double.toString(m3));
BigDecimal p4 = new BigDecimal(Double.toString(m4));
return p1.add(p2).add(p3).add(p4).doubleValue();
}
public static String getDouble2String(Double doubleValue) {
return String.valueOf(new BigDecimal(String.valueOf(doubleValue)));
}
/**
* 针对字符串的数值型
* 利用反射形成合计数据
* 通过clazz.newInstance()构造合计数据行
* 循环处理每一个IFunction,可以看出1、2出代码就是上方获取aa、bb累计
* 通过get方法获取对应的set方法
* 给第一步构造的数据执行set方法赋值
*
* @param clazz
* @param list
* @param mappers
* @param
* @return
*/
public static <T> T mapperSumString(Class<T> clazz, List<T> list, IFunction<? super T, ? extends String>... mappers) {
try {
List<String> data;
T o = clazz.newInstance();
for (IFunction<? super T, ? extends String> mapper : mappers) {
data = list.stream().map(mapper).filter(Objects::nonNull).collect(Collectors.toList());
String add = getDouble2String(data.stream().mapToDouble(MathUtil::getDouble).sum());
String setMethod = setMethodString(mapper);
Method method = clazz.getMethod(setMethod, String.class);
method.invoke(o, add);
}
return o;
} catch (Exception e) {
throw new ServiceException("数据异常!");
}
}
/**
* 针对数值型
* @param clazz
* @param list
* @param mappers
* @return
* @param
*/
public static <T> T mapperSum(Class<T> clazz, List<T> list, IFunction<? super T, ? extends Double>... mappers) {
try {
List<Double> data;
T o = clazz.newInstance();
for (IFunction<? super T, ? extends Double> mapper : mappers) {
data = list.stream().map(mapper).filter(Objects::nonNull).collect(Collectors.toList());
Double add = data.stream().mapToDouble(x ->x).sum();
String setMethod = setMethod(mapper);
Method method = clazz.getMethod(setMethod, Integer.class);
method.invoke(o, add);
}
return o;
} catch (Exception e) {
throw new ServiceException("数据异常!");
}
}
private static <T> String setMethodString(IFunction<? super T, ? extends String> func) {
String implMethodName = func.getImplMethodName();
String substring = implMethodName.substring(3);
return "set" + substring;
}
private static <T> String setMethod(IFunction<? super T, ? extends Double> func) {
String implMethodName = func.getImplMethodName();
String substring = implMethodName.substring(3);
return "set" + substring;
}
public static void main(String[] args) {
/*Double doubleMul = getDoubleMul("1111.11", "2222.22", "3333.39");
System.out.println(getDouble2String(doubleMul));
System.out.println(getDoubleMulStr("1111.11", "2222.22", "3333.39"));
System.out.println(getDoubleMulStr("", "2222.22", "3333.39"));
System.out.println(getDoubleMulStr(null, "2222.22", "3333.39"));*/
String annual = MathUtil.getDoubleMulStr("1111.11", "2222.22", "3333.34", "4444.44");
}
}
3、涉及到的IFunction接口
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.function.Function;
@FunctionalInterface
public interface IFunction<T, R> extends Function<T, R>, Serializable {
default SerializedLambda getSerializedLambda(){
Method write;
try {
write = this.getClass().getDeclaredMethod("writeReplace");
write.setAccessible(true);
return (SerializedLambda) write.invoke(this);
} catch (Exception e) {
throw new IllegalArgumentException();
}
}
default String getImplClass() {
return getSerializedLambda().getImplClass();
}
default String getImplMethodName() {
return getSerializedLambda().getImplMethodName();
}
}