public class PercentUtils {
public static String getPercentValue(List<Long> elementList, int idx, int precision) {
if ((elementList.size()) < idx) {
return BigDecimal.ZERO.toString();
}
LongSummaryStatistics statistics = elementList.stream().collect(Collectors.summarizingLong(value -> value));
BigDecimal sum = BigDecimal.valueOf(statistics.getSum());
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);
}
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;
}
}
BigDecimal maxVal = seats.get(maxId);
seats.set(maxId, maxVal.add(BigDecimal.ONE));
remainder.set(maxId, BigDecimal.ZERO);
currentSum = currentSum.add(BigDecimal.ONE);
}
BigDecimal result = seats.get(idx).divide(targetSeats);
NumberFormat percentInstance = NumberFormat.getPercentInstance();
percentInstance.setMaximumFractionDigits(precision);
return percentInstance.format(result);
}
}