概述
场景:现在有数组 [10,40,0,50],计算10的百分比为10%,40为40%,0为0%,50为50%,和为100%
/**
* 计算元素占比
*
* @param elementList 元素集合
* @param idx 元素索引
* @param precision 精度
* @return 结果20%,返回20%
*/
public static String getPercentValue(List<Long> elementList, int idx, int precision) {
if(CollUtil.isEmpty(elementList)){
return "0";
}
//校验索引越界
if ((elementList.size()-1) < idx) {
return BigDecimal.ZERO.toString();
}
//对元素集合所有元素进行求和
LongSummaryStatistics statistics = elementList.stream().collect(Collectors.summarizingLong(value -> value));
BigDecimal sum = BigDecimal.valueOf(statistics.getSum());
if(sum.compareTo(BigDecimal.ZERO) == 0){
return "0";
}
//10的2次幂是100,用于计算精度。
BigDecimal digits = BigDecimal.valueOf(Math.pow(10, precision));
//计算每个元素在元素集合中的占比,且扩大比例
List<BigDecimal> votesPerQuota = Lists.newArrayListWithCapacity(elementList.size());
for (Long element : elementList) {
BigDecimal elementDecimal = BigDecimal.valueOf(element);
BigDecimal val = elementDecimal.divide(sum, 6, BigDecimal.ROUND_DOWN).multiply(digits).multiply(new BigDecimal(100));
votesPerQuota.add(val);
}
//总数,扩大比例意味的总数要扩大
BigDecimal targetSeats = digits.multiply(new BigDecimal(100));
//再向下取值,组成向下取值的元素集合
List<BigDecimal> seats = Lists.newArrayListWithCapacity(elementList.size());
for (BigDecimal element : votesPerQuota) {
BigDecimal val = element.setScale(0, BigDecimal.ROUND_FLOOR);
seats.add(val);
}
//重新计算元素总和,用于判断与总数量是否相同,相同则占比会100%
BigDecimal currentSum = BigDecimal.ZERO;
for (BigDecimal element : seats) {
currentSum = currentSum.add(element);
}
//余数部分的数组:原先数组减去向下取值的数组,得到余数部分的数组
List<BigDecimal> remainder = Lists.newArrayListWithCapacity(elementList.size());
for (int i = 0; i < seats.size(); i++) {
BigDecimal voteVal = votesPerQuota.get(i);
BigDecimal subtract = voteVal.subtract(seats.get(i));
remainder.add(subtract);
}
//如果向下取值的数组元素总和等于原集合总和,就不进入循环
while (targetSeats.compareTo(currentSum) == 1) {
BigDecimal max = BigDecimal.ZERO;
int maxId = 0;
for (int i = 0; i < remainder.size(); i++) {
BigDecimal element = remainder.get(i);
if (element.compareTo(max) == 1) {
max = element;
maxId = i;
}
}
//对最大项元素的值加1
BigDecimal maxVal = seats.get(maxId);
seats.set(maxId, maxVal.add(BigDecimal.ONE));
//已经增加最大余数加1,则下次判断就可以不需要再判断这个余额数。
remainder.set(maxId, BigDecimal.ZERO);
//总的也要加1,为了判断是否总数是否相同,跳出循环。
currentSum = currentSum.add(BigDecimal.ONE);
}
// 这时候的seats就会总数占比会100%,计算当前元素值占比即可
BigDecimal result = seats.get(idx).divide(targetSeats);
NumberFormat percentInstance = NumberFormat.getPercentInstance();
percentInstance.setMaximumFractionDigits(precision);
return percentInstance.format(result);
}
最后
以上就是多情指甲油为你收集整理的java 计算百分比占比,占比和为100%的全部内容,希望文章能够帮你解决java 计算百分比占比,占比和为100%所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复