Вы можете использовать решение для регулярных диапазонов, например,
BigDecimal range = BigDecimal.valueOf(25);
inputMap.values().stream()
.collect(Collectors.groupingBy(
bd -> bd.subtract(BigDecimal.ONE).divide(range, 0, RoundingMode.DOWN),
TreeMap::new, Collectors.counting()))
.forEach((group,count) -> {
group = group.multiply(range);
System.out.printf("%3.0f - %3.0f: %s%n",
group.add(BigDecimal.ONE), group.add(range), count);
});
который напечатает:
1 - 25: 2
51 - 75: 1
76 - 100: 1
(без использования нерегулярного диапазона 0 - 25
)
или решение с явными диапазонами:
TreeMap<BigDecimal,String> ranges = new TreeMap<>();
ranges.put(BigDecimal.ZERO, " 0 - 25");
ranges.put(BigDecimal.valueOf(26), "26 - 50");
ranges.put(BigDecimal.valueOf(51), "51 - 75");
ranges.put(BigDecimal.valueOf(76), "76 - 99");
ranges.put(BigDecimal.valueOf(100),">= 100 ");
inputMap.values().stream()
.collect(Collectors.groupingBy(
bd -> ranges.floorEntry(bd).getValue(), TreeMap::new, Collectors.counting()))
.forEach((group,count) -> System.out.printf("%s: %s%n", group, count));
0 - 25: 2
51 - 75: 1
76 - 99: 1
, который также может быть расширен для печати отсутствующих диапазонов:
Map<BigDecimal, Long> groupToCount = inputMap.values().stream()
.collect(Collectors.groupingBy(bd -> ranges.floorKey(bd), Collectors.counting()));
ranges.forEach((k, g) -> System.out.println(g+": "+groupToCount.getOrDefault(k, 0L)));
0 - 25: 2
26 - 50: 0
51 - 75: 1
76 - 99: 1
>= 100 : 0
Но учтите, что размещение числовых значений в таких диапазонах, как, например, «0 - 25» и «26 - 50» имеют смысл, только если мы говорим о целых числах, исключая значения между 25 и 26, и возникает вопрос, почему вы используете BigDecimal
вместо BigInteger
. Для десятичных чисел вы обычно используете диапазоны, такие как «0 (включительно) - 25 (исключая)» и «25 (включительно) - 50 (исключая)» и т. Д.