计算出一组数字几个比重均匀分布的范围,类似京东价格显示范围的效果


商城中每个商品都有自己的价格,下面的工具类可生成一组价格范围供用户选择。


package 范围计算;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 计算出一组数字几个比重均匀分布的范围
 *
 * @Author: Heiffeng
 * @Date: 2022/2/14 16:45
 */
public class NumRangeCal {


    public static Range[] cal(List list,int rangeCount){
        // 计算数量
        Map map = new HashMap<>();
        list.forEach(integer -> {
            if(map.containsKey(integer)){
                map.put(integer,map.get(integer)+1);
            }else{
                map.put(integer,1);
            }
        });
        // 去重,排序
        List sorted = list.stream()
                .collect(Collectors.toSet())
                .stream()
                .sorted()
                .collect(Collectors.toList());

        Integer[] result = new Integer[rangeCount+1];
        result[0] = sorted.get(0);
        int split = (int)(100f/rangeCount);
        for (int i = 1,j = 0,count = 0;i < result.length && j < sorted.size(); j++) {
            count += map.get(sorted.get(j));
            int per = (int)(((float)count / list.size())*100);
            if(per > split * i){
                result[i] = sorted.get(j);
                i++;
            }
        }
        result[rangeCount] = sorted.get(sorted.size()-1);
        Range[] ranges = new Range[rangeCount];
        for (int i = 1; i < result.length; i++) {
            Range range = Range.builder()
                    .min(result[i - 1])
                    .max(result[i])
                    .build();
            int count = list.stream()
                    .filter(num -> (range.getMin() <= num && num <= range.getMax()))
                    .collect(Collectors.toList())
                    .size();
            range.setCount(count);
            ranges[i-1] = range;
        }
        return ranges;
    }

    public static void main(String[] args) {
        Range[] ranges = cal(
                Arrays.asList(177, 177, 75, 75, 56, 73, 73, 67, 176, 145, 138, 143, 142, 150, 150, 177, 177, 148, 150, 150, 75, 75, 75, 75, 76, 75, 68, 68, 68, 68, 68, 68, 68, 68, 68, 177, 177, 177, 177, 177, 178, 179, 149, 183, 149, 150, 177, 73, 177, 177, 177, 177, 66, 177, 177, 177, 149, 149, 149, 149, 177, 150, 150, 149, 177, 150, 55, 177, 177, 149, 148, 150, 149, 149, 177, 75, 156, 177, 177, 149, 148, 177, 177, 177, 136, 70, 93, 178, 149, 66, 70, 150, 149, 177, 177, 177, 148, 150, 177, 177, 160, 150, 149, 177, 66, 66, 177, 149, 150, 150, 133, 150, 133, 133, 149, 177, 177, 177, 177, 75, 177, 149, 66, 150, 150, 150, 150, 150, 177, 150, 66, 168, 174, 177, 177, 177, 177, 177, 177, 149, 177, 177, 150, 150, 150, 148, 150, 150, 149, 149, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 150, 66, 150, 177, 177, 177, 150, 100, 100, 123, 123, 73, 179, 102, 70, 75, 65, 75, 75, 37, 37, 24, 38, 78, 70, 66, 66, 68, 70, 150, 66, 66, 22, 75, 75, 24, 25, 25, 22, 48, 37, 37, 48, 40, 25, 37, 177, 177, 177, 66, 177, 148, 75, 75, 75, 75, 75, 149, 66, 149, 66, 149, 66, 133, 133, 133, 66, 147, 177, 177, 34, 149, 177, 177, 148, 142, 141, 138, 150, 150, 177, 150, 177, 165, 150, 148, 66, 149, 177, 66, 62, 177, 177, 177, 148, 66, 149, 66, 149, 149, 149, 149, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 133, 150, 150, 150, 149, 177, 177, 149, 150, 177, 177, 150, 66, 150, 150, 150, 150, 150, 149, 177, 149, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 149, 177, 177, 62, 160, 150, 177, 177, 150, 66, 160, 149, 148, 149, 56, 177, 177, 66, 150, 149, 177, 177, 149, 180, 148, 150, 177, 148, 66, 133, 177, 148, 150, 150, 177, 177, 133, 148, 66, 133, 177, 149, 66, 66, 150, 177)
                ,4
        );
        for (Range range : ranges) {
            System.out.println(range);
        }

    }


    @Data
    @Builder
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    static class Range{
        private Integer min;
        private Integer max;
        private Integer count;
    }

}


计算结果如下:

RangeCalUtil.Range(min=22, max=93, count=92)
RangeCalUtil.Range(min=93, max=150, count=130)
RangeCalUtil.Range(min=150, max=177, count=177)
RangeCalUtil.Range(min=177, max=183, count=124)

代码详见:https://gitee.com/heika/research-java/blob/main/src/main/java/范围计算/NumRangeCal.java