private Map<String, BigDecimal> calAmountPercent(List<AmountPercentInfo> amountDistList, int decimalNum){
Map<String, BigDecimal> amountDistMap = Maps.newHashMap();
if (CollectionUtils.isEmpty(amountDistList) || decimalNum<0){
return amountDistMap;
}
if (amountDistList.size()==1){
amountDistMap.put(amountDistList.get(0).getItemKey(), BigDecimal.ONE);
return amountDistMap;
}
BigDecimal totalAmount = BigDecimal.ZERO;
for(AmountPercentInfo amountPercentInfo: amountDistList) {
totalAmount = totalAmount.add(amountPercentInfo.getItemAmount());
}
List<AmountPercentInfo> lostItems = Lists.newArrayList();
BigDecimal sum = BigDecimal.ZERO;
for (AmountPercentInfo percentInfo : amountDistList) {
BigDecimal source = percentInfo.getItemAmount()
.divide(totalAmount, decimalNum+2, BigDecimal.ROUND_HALF_UP);
BigDecimal reserve = source.setScale(decimalNum, BigDecimal.ROUND_DOWN);
BigDecimal lost = source.subtract(reserve);
if (lost.signum()>0){
AmountPercentInfo lostInfo = new AmountPercentInfo();
lostInfo.setItemKey(percentInfo.getItemKey());;
lostInfo.setItemPercent(lost);
lostItems.add(lostInfo);
}
amountDistMap.put(percentInfo.getItemKey(), reserve);
sum = sum.add(reserve);
}
if (sum.compareTo(BigDecimal.ONE)<0){
BigDecimal error = BigDecimal.ONE.subtract(sum);
BigDecimal unit =BigDecimal.ONE.divide(BigDecimal.TEN.pow(decimalNum), decimalNum, BigDecimal.ROUND_HALF_UP);
Collections.sort(lostItems, new Comparator<AmountPercentInfo>() {
@Override
public int compare(AmountPercentInfo r1,
AmountPercentInfo r2) {
BigDecimal lost1 = r1.getItemPercent();
BigDecimal lost2 = r2.getItemPercent();
return lost2.compareTo(lost1);
}
});
for(AmountPercentInfo lostInfo : lostItems){
String itemKey = lostInfo.getItemKey();
amountDistMap.put(itemKey, amountDistMap.get(itemKey).add(unit));
error = error.subtract(unit);
if (error.signum()<=0){
break;
}
}
}
return amountDistMap;
}