有时候业务上会有多个数求和、求平均数的操作,那么怎么才能更优雅、更高级的实现呢? 我这边的实现方式如下:
- 核心逻辑如下:
import java .util.concurrent.atomic.AtomicReference;
public class CountUtil {
private static final Integer DEAULT_INTGER = 0;
/**
* 求N个数的平均值
*
* @param u
* @param n
* @param <U>
* @return
*/
public static <U extends Number> U avg(Class<U> u, U... n) {
if (PredicateUtil.isAnyEmpty(u, n)) {
return null ;
}
return NumberUtil.divide(sum(u, n), n.length, u, DEAULT_INTGER);
}
/**
* 求N的数的总和
*
* @param u
* @param n
* @param <U>
* @return
*/
public static <U extends Number> U sum(Class<U> u, U... n) {
if (PredicateUtil.isAnyEmpty(u, n)) {
return null;
}
if (Integer.class.isAssignableFrom(u)) {
AtomicReference<Integer> count = new AtomicReference(DEAULT_INTGER);
ForConsumer<U> forConsumer = (t) -> {
if (PredicateUtil.isNotEmpty(t)) {
count.set(count.get() + (Integer) t);
}
};
ForUtil.foreach(forConsumer, n);
return (U) count.get();
} else if (Float.class.isAssignableFrom(u)) {
AtomicReference<Float> count = new AtomicReference(DEAULT_INTGER);
ForConsumer<U> forConsumer = (t) -> {
if (PredicateUtil.isNotEmpty(t)) {
count.set(count.get() + (Float) t);
}
};
ForUtil.foreach(forConsumer, n);
return (U) count.get();
} else if (Double.class.isAssignableFrom(u)) {
AtomicReference<Double> count = new AtomicReference(DEAULT_INTGER);
ForConsumer<U> forConsumer = (t) -> {
if (PredicateUtil.isNotEmpty(t)) {
count.set(count.get() + (Double) t);
}
};
ForUtil.foreach(forConsumer, n);
return (U) count.get();
} else if (Long.class.isAssignableFrom(u)) {
AtomicReference<Long> count = new AtomicReference(DEAULT_INTGER);
ForConsumer<U> forConsumer = (t) -> {
if (PredicateUtil.isNotEmpty(t)) {
count.set(count.get() + (Long) t);
}
};
ForUtil.foreach(forConsumer, n);
return (U) count.get();
}
return (U) DEAULT_INTGER;
}
}
循环工具类
public class ForUtil {
public static <T> void foreach(List<T> lst, ForConsumer<List<T>> consumer) {
if (!CollectionUtils.isEmpty(lst)) {
consumer.accept(lst);
}
}
public static <U extends Object> void foreach(ForConsumer<U> consumer, U[] o) {
if (PredicateUtil.isAnyEmpty(consumer, o)) {
return;
}
Stream.of(o).forEach(item -> {
consumer.accept(item);
});
}
}
- 自定义Consumer如下:
import java.util.Objects;
@FunctionalInterface
public interface ForConsumer<T> {
void accept(T t);
default ForConsumer<T> andThen(ForConsumer<T> after) {
Objects.requireNonNull(after);
return (x) -> {
accept (x);
after.accept(x);
};
}
}
- 具体用法:
CountUtil.sum(n1,n2,n3,n4,n5,n6.......)