Java8 排序、分组、统计、过滤

本文深入探讨了Java8 Stream API的高效使用方法,通过具体案例展示了如何利用Stream进行数据处理,包括排序、分组、统计和过滤等操作,旨在帮助开发者写出更简洁、清晰的代码。

Java 8 Stream,可以以一种声明的方式处理数据,写出高效率、干净、简洁的代码,可以在节点上进行处理, 比如筛选, 排序,聚合等。

 

测试的实体:

@Data
public class City {

    private String cityName;//城市名称

    private Integer population;//人口

    private Integer rank;//排名

    private String province;//所属省份名称

    public City(String cityName, Integer population, Integer rank, String province) {
        this.cityName = cityName;
        this.population = population;
        this.rank = rank;
        this.province = province;
    }
}

测试排序、分组、统计、过滤:


    private static final List<String> sortArray = Arrays.asList("西安", "济南","洛阳","宝鸡","德州","开封","枣庄","榆林","郑州","菏泽","渭南","新乡");

    public static void main(String[] args) {

        List<City> list = new ArrayList<>();
        formData(list);//组建测试数据

        /*=========================排序====================================================*/

        //根据某个字段升序排序。注意:若是排序的字段值有空,此排序方式会报空指针异常,使用第二种排序方式
        list.sort(Comparator.comparing(City::getRank));
        list.sort(Comparator.comparing(City::getRank,Comparator.nullsFirst(Integer::compareTo)));
        //根据排名字段降序排序
        list.sort((e0, e1) -> e1.getRank().compareTo(e0.getRank()));
        list.sort(Comparator.comparing(City::getRank,Comparator.nullsFirst(Integer::compareTo)).reversed());
        //根据固定的城市名称顺序排列
        Collections.sort(list,(e0,e1) -> {
            int index0 = sortArray.indexOf(e0.getCityName());
            int index1 = sortArray.indexOf(e1.getCityName());
            return index0-index1;
        });
        System.out.println(JSONObject.toJSONString(list));

        //按照多个字段排序,先按照省份排序,后按照排名排序

        List<City> collect = list.stream().sorted(Comparator.comparing(City::getProvince).thenComparing(City::getRank)).collect(Collectors.toList());

        //先按照一个字段排序,再按照另一个字段降序
            list.sort(Comparator.comparing(City::getProvince).thenComparing(City::getRank,Comparator.reverseOrder()));
        System.out.println(list);

        //=======================分组================================
        //根据省份分组
        Map<String, List<City>> provinceMap = list.stream().collect(Collectors.groupingBy(City::getProvince));
        for (Map.Entry<String,List<City>> map: provinceMap.entrySet()) {
            System.out.println("省份:"+map.getKey()+",城市:"+map.getValue());
        }

        //根据省份+排名 分组
        Map<String, List<City>> provinceRankMap = list.stream().collect(Collectors.groupingBy(u->(u.getProvince()+"_"+u.getRank() )));
        for (Map.Entry<String,List<City>> map: provinceRankMap.entrySet()) {
            System.out.println("省份+排名:"+map.getKey()+",城市:"+map.getValue());
        }


        //根据省份分组求每省总人口
        Map<String, Integer> provinceSumMap = list.stream().collect(Collectors.groupingBy(City::getProvince,Collectors.summingInt(City::getPopulation)));
        for (Map.Entry<String,Integer> map: provinceSumMap.entrySet()) {
            System.out.println("省份:"+map.getKey()+",人口:"+map.getValue());
        }

        //根据省份分组求每省市平均人口
        Map<String, Double> provinceAvgMap = list.stream().collect(Collectors.groupingBy(City::getProvince,Collectors.averagingInt(City::getPopulation)));
        for (Map.Entry<String,Double> map: provinceAvgMap.entrySet()) {
            System.out.println("省份:"+map.getKey()+",每市人口平均数:"+map.getValue());
        }

        //=======================过滤================================

        //过滤获得人口数大于3000的城市
        List<City> collect = list.stream().filter(entity -> entity.getPopulation() > 3000).collect(Collectors.toList());
        System.out.println(JSONObject.toJSONString(collect));

        //map 获取list中实体的某个字段的集合
        List<String> map=list.stream().map(City::getCityName).collect(Collectors.toList());
        System.out.println("stream -> map :"+map);

        //===========================匹配===========================

        //全匹配,都符合条件的话返回true,否则返回false
        boolean allMatch = list.stream().allMatch(city -> city.getCityName().equals("榆林"));
        System.out.println("stream -> allMatch :"+allMatch);
        //部分匹配,只要有一个是的话返回true,全不是返回false
        boolean anyMatch = list.stream().anyMatch(city -> city.getCityName().equals("榆林"));
        System.out.println("stream -> anyMatch :"+anyMatch);
        //某字段的最大值
        City maxRankCity = list.stream().max(Comparator.comparing(City::getRank)).get();
        System.out.println("stream -> max :"+maxRankCity);
        City minRankCity = list.stream().min(Comparator.comparing(City::getRank)).get();
        System.out.println("stream -> min :"+minRankCity);

        //        reduce	归约,将流中元素反复结合起来得到一个值
        List<Integer> IntegerList = Arrays.asList(1,2,3,4,5,6);
        Integer reduce = IntegerList.stream().reduce(0, Integer::sum);
        System.out.println("stream -> reduce :"+reduce);

        //求和
        int sum = list.stream().filter(e->null != e.getPopulation()).mapToInt(City::getPopulation).sum();

        //根据城市字段名称去重
        Set<City> set = new TreeSet<>(Comparator.comparing(City::getCityName));
        set.addAll(list);
        list = new ArrayList<>(set);
        System.out.println(JSONObject.toJSONString(list));
    }

    private static void formData(List<City> list) {
        City city = new City("菏泽",2345,16,"山东");
        City city1 = new City("枣庄",2945,11,"山东");
        City city2 = new City("德州",8345,17,"山东");
        City city3 = new City("济南",8945,13,"山东");

        City city4 = new City("郑州",4670,18,"河南");
        City city5 = new City("开封",4550,21,"河南");
        City city6 = new City("洛阳",4580,27,"河南");
        City city7 = new City("新乡",4530,23,"河南");

        City city8 = new City("西安",2339,5,"陕西");
        City city9 = new City("渭南",2724,22,"陕西");
        City city10 = new City("宝鸡",3671,7,"陕西");
        City city11 = new City("榆林",4357,24,"陕西");
        list.add(city);
        list.add(city1);
        list.add(city2);
        list.add(city3);
        list.add(city4);
        list.add(city5);
        list.add(city6);
        list.add(city7);
        list.add(city8);
        list.add(city9);
        list.add(city10);
        list.add(city11);
    }

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值