直接附上util类
NumberEnum.ONE_HUNDRED.getCode() 为 100 也就是你要的最终和为多少
public class PercentageCalculatorUtil {
@Data
private static class IdDecimalTuple {
/**
* 传送的对象
*/
private Option id;
/**
* 精度
*/
private BigDecimal decimal;
IdDecimalTuple(Option id, BigDecimal decimal) {
this.id = id;
this.decimal = decimal;
}
}
@Data
public static class Option {
/**
* 原数字
*/
private Integer voteCount;
/**
* 占的百分比
*/
private Integer percentage;
/**
* 唯一标识
*/
private String codeStr;
/**
* 唯一编码
*/
@JSONField(serializeUsing = ToStringSerializer.class)
private Long code;
public Option(Integer voteCount, Long code) {
this.voteCount = voteCount;
this.code = code;
}
public Option(Integer voteCount, String codeStr) {
this.voteCount = voteCount;
this.codeStr = codeStr;
}
}
public static List<Option> computePercentage(List<Option> src) {
Integer total = src.stream().map(Option::getVoteCount).reduce(0, Integer::sum);
BigDecimal totalBigDecimal = BigDecimal.valueOf(total);
BigDecimal hundredBigDecimal = BigDecimal.valueOf(NumberEnum.ONE_HUNDRED.getCode());
List<IdDecimalTuple> decimalPartList = new LinkedList<>();
src.forEach(votable -> {
BigDecimal percentage = BigDecimal.valueOf(votable.getVoteCount())
.divide(totalBigDecimal, 6, RoundingMode.FLOOR).multiply(hundredBigDecimal);
votable.setPercentage(percentage.setScale(0, RoundingMode.FLOOR).intValue());
decimalPartList.add(new IdDecimalTuple(votable, percentage.remainder(BigDecimal.ONE)));
});
Integer totalPercentage = src.stream().map(Option::getPercentage).reduce(0, Integer::sum);
if (Objects.equals(totalPercentage, NumberEnum.ONE_HUNDRED.getCode())) {
return src;
}
List<IdDecimalTuple> sortedEntry = decimalPartList.stream().sorted(Comparator.comparing(
IdDecimalTuple::getDecimal).reversed()).collect(
Collectors.toList());
IntStream.range(0, NumberEnum.ONE_HUNDRED.getCode() - totalPercentage).mapToObj(i -> sortedEntry.get(i).getId()).forEach(option -> option.setPercentage(option.getPercentage() + 1));
return src;
}
public static void main(String[] args) {
Option a1 = new Option(1, 111L);
Option a2 = new Option(1, 222L);
Option a3 = new Option(1, 333L);
Option a4 = new Option(1, 444L);
Option a5 = new Option(12, 555L);
Option a6 = new Option(6, 666L);
List<Option> options = Arrays.asList(a1, a2, a3, a4, a5, a6);
List<Option> options1 = computePercentage(options);
System.out.println(JSON.toJSONString(options1));
}
}