JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序

JAVA8新特性之List的各种用法

    • 一、根据字段分组得到多个List集合
      • 1.1 根据性别分组效果如图所示
    • 二、集合求和
      • 2.1 根据对象中的某个字段求和
        • 2.1.1 根据年龄求和效果如图所示
      • 2.2 List<数值型> 求和
        • 2.2.1 List<数值型> 求和效果图
    • 三、遍历List集合
      • 3.1 遍历效果图
    • 四、过滤List集合
      • 4.1 根据年龄字段过滤数据效果
    • 五、获取List中的最大最小值
      • 5.1 根据特定需求中的某个字段求最大最小
      • 5.1.1 根据字段求最大最小值效果图
      • 5.2 根据特定需求中的某个字段求平均值
    • 六、根据需求将List转为Map
      • 6.1 根据需求将List转为map效果图
    • 七、List排序
      • 7.1 排序效果图
    • 八、List去重
      • 8.1 List去重效果图
    • 九、List的合并
      • 9.1 List的合并之--->并集
      • 9.1.1 List的合并之--->并集效果图
      • 9.2 List的合并之--->交集(即两个或多个list重复的元素的集合)
      • 9.2.1 List的合并之--->交集效果图

所有的代码均以User对象来做案例,有不对或者错误的地方请各位J友多多担待和指出.
实体类:

import java.math.BigDecimal;
import java.util.Date;

/**
 * 实体类
 * @author 12084
 * @create 2019-08-05 10:04
 */
public class Users {
    /**
     * ID
     */
    private Long id;
    /**
     * 用户名
     */
    private String name;
    /**
     * 年龄
     */
    private int age;
    /**
     * 工号
     */
    private String jobNumber;
    /**
     * 性别
     */
    private String sex;
    /**
     * 注册时间
     */
    private Date entryDate;
    /**
     * 成员组织
     */
    private BigDecimal familyMemberQuantity;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJobNumber() {
        return jobNumber;
    }

    public void setJobNumber(String jobNumber) {
        this.jobNumber = jobNumber;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getEntryDate() {
        return entryDate;
    }

    public void setEntryDate(Date entryDate) {
        this.entryDate = entryDate;
    }

    public BigDecimal getFamilyMemberQuantity() {
        return familyMemberQuantity;
    }

    public void setFamilyMemberQuantity(BigDecimal familyMemberQuantity) {
        this.familyMemberQuantity = familyMemberQuantity;
    }

    @Override
    public String toString() {
        return "Users{" +
                "用户ID=" + id +
                ", 用户姓名='" + name + '\'' +
                ", 用户年龄=" + age +
                ", 用户工号='" + jobNumber + '\'' +
                ", 用户性别='" + sex + '\'' +
                ", 用户注册时间=" + entryDate +
                ", 用户家庭成员数量=" + familyMemberQuantity +
                '}';
    }
}

一、根据字段分组得到多个List集合

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 12084
 * @create 2019-08-05 10:04
 */
public class ListLambdaTest {
    public static final Logger logger = LoggerFactory.getLogger(ListLambdaTest.class);
    /**
     * 生产虚拟用户
     * @return
     */
    public  List<Users> produceUser(){
        List<Users> usersList = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            Users users = new Users();
            users.setId(Long.valueOf(i));
            users.setName("kobe" + i);
            users.setAge(i);
            users.setJobNumber("jobNumber" + i);
            if (i % 2 == 0) {
                users.setSex("男");
            } else {
                users.setSex("女");
            }
            users.setEntryDate(new Date());
            users.setFamilyMemberQuantity(new BigDecimal(i));
            usersList.add(users);
        }
        return usersList;
    }
    /**
     * 利用Java8 特性,根据对象的某个属性进行分组
     */
    @Test
    public void groupByJava8(){
        List<Users> list = produceUser();
        //根据性别进行分组
        Map<String, List<Users>> collect = list.stream().collect(Collectors.groupingBy(Users::getSex));
        Set<Map.Entry<String, List<Users>>> entrySet = collect.entrySet();
        //使用增强for循环
        for (Map.Entry<String, List<Users>> listEntry : entrySet) {
            //性别 男 / 女
            String sex = listEntry.getKey();
            // 男集合 / 女集合
            List<Users> usersList = listEntry.getValue();
            // 下面写法跟上面listEntry.getValue()一致,无任何差别
            //List users = collect.get(sex);
            System.out.println("性别:"+sex);
            for (Users users : usersList) {
                System.out.println(users);
            }
        }
    }
}

1.1 根据性别分组效果如图所示

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第1张图片

二、集合求和

2.1 根据对象中的某个字段求和

     /**
     * 根据年龄字段求总和
     */
    @Test
    public void getSumByJava8() {
        List<Users> list = produceUser();
        //这里age属性是int类型可以直接求和
        int sum = list.stream().mapToInt(Users::getAge).sum();
        //假设这里age属性是String类型也可以求和,只不过有个前提,要能转成基本数据类型中的数值型
        //double sum1 = list.stream().mapToDouble(s -> Integer.valueOf(s.getAge())).sum();
        System.out.println("共计:" + list.size() + "个用户,所有年龄总和为:" + sum);

    }

2.1.1 根据年龄求和效果如图所示

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第2张图片

2.2 List<数值型> 求和

   /**
     * 根据List求和
     */
    @Test
    public void getListSumByJava8() {
        List<Integer> list = new ArrayList();
        List<Double> lisst = new ArrayList();
        for (int i =1000; i <1500 ; i++) {
            list.add(i);
            lisst.add((double) i);
        }
        System.out.println("=======数值型Integer求和======");
        Integer integer = list.stream().reduce(Integer::sum).orElse(0);
        System.out.println(integer);
        System.out.println("=======数值型Double求和======");
        Double integer1 = lisst.stream().reduce(Double::sum).orElse(0.00);
        System.out.println(integer1);

    }

2.2.1 List<数值型> 求和效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第3张图片

三、遍历List集合

    /**
     * 遍历对象
     */
    @Test
    public void traverseByJava8(){
        List<Users> list = produceUser();
        list.stream().forEach(s-> {
            System.out.println(s.toString());
        });
    }

3.1 遍历效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第4张图片

四、过滤List集合

   /**
     * 过滤对象
     */
    @Test
    public void filterByJava8(){
        List<Users> list = produceUser();
        System.out.println("原始数据为:"+list.toString());
        System.out.println("==============过滤后的数据为===============");
        //筛选出年龄大于3岁小于8岁的对象
        List<Users> collect = list.stream().filter(s -> s.getAge()>3 &&s.getAge() < 8).collect(Collectors.toList());
        System.out.println("过滤结束后的数据为:"+collect.toString());
    }

4.1 根据年龄字段过滤数据效果

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第5张图片

五、获取List中的最大最小值

5.1 根据特定需求中的某个字段求最大最小

  /**
     * 求最大最小值,根据业务类型选择合适的类型值
     */
    @Test
    public void maxOrMinByJava8(){
        List<Users> list = produceUser();
        //根据mapTO**得到最大最小  ---写法一
        double asDouble = list.stream().mapToDouble(Users::getAge).max().getAsDouble();
        System.out.println("将最大值转换为Double类型进行展示,最大为:"+asDouble);
        double asDouble1 = list.stream().mapToDouble(Users::getAge).min().getAsDouble();
        System.out.println("将最小值转换为Double类型进行展示,最小为:"+asDouble1);
        int asInt = list.stream().mapToInt(Users::getAge).max().getAsInt();
        System.out.println("将最大值转换为Int类型进行展示,最大为:"+asInt);
        //根据map得到最大最小  ---写法二(推荐)
        Integer integer = list.stream().map(Users::getAge).max(Integer::compareTo).get();
        System.out.println("将最大值转换为字段对应类型进行展示,最大为:"+integer);
        Integer integer1 = list.stream().map(Users::getAge).min(Integer::compareTo).get();
        System.out.println("将最小值转换为字段对应类型进行展示,最小为:"+integer1);

    }

5.1.1 根据字段求最大最小值效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第6张图片

5.2 根据特定需求中的某个字段求平均值

   /**
     * 求最大最小值,根据业务类型选择合适的类型值
     */
    @Test
    public void avgByJava8(){
    List<Users> list = produceUser();
    double avgAge = list.stream().mapToDouble(Users::getAge).average().getAsDouble();
    System.out.println("平均年龄为:"+avgAge );
}


六、根据需求将List转为Map

  /**
     * List -> Map
     * 需要注意的是:
     * toMap 如果集合对象有重复的key,会报错Duplicate key ....
     * user1,user2的id都为1。
     * 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
     */
    @Test
    public void mapToListByJava8() {
        List<Users> list = produceUser();
        Map<Long, Users> map = list.stream().collect(Collectors.toMap(Users::getId, a -> a, (k1, k2) -> k1));
        for (Map.Entry<Long, Users> entry : map.entrySet()) {
            Long key = entry.getKey();
            System.out.println("map中的key是:"+key);
            System.out.println("map中的value是:"+entry.getValue().toString());
        }
    }

6.1 根据需求将List转为map效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第7张图片

七、List排序

  /**
     * 排序(单字段/多字段排序)
     */
    @Test
    public void sortByJava8() {
        List<Users> list = produceUser();
        System.out.println("============未排序的数据=============");
        System.out.println(list.toString());
        try {
            //单字段排序,根据名字排序
            System.out.println("============单字段排序,根据名字排序=============");
            list.sort(Comparator.comparing(Users::getName));
            System.out.println(list.toString());
            //多字段排序,根据年龄再根据-->名字排序
            System.out.println("============多字段排序,根据年龄再根据-->名字排序=============");
            list.sort(Comparator.comparing(Users::getAge, (o1, o2) -> o2 - o1).thenComparing(Users::getName));
            System.out.println(list.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

7.1 排序效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第8张图片

八、List去重

 /**
     * 去重
     */
    @Test
    public void distinctByJava8() {
        List<String> numList = new ArrayList();
        numList.add("sss");
        numList.add("sss");
        numList.add("sss1");
        numList.add("sss2");
        numList.add("sss1");
        numList.add("sss2");
        System.out.println("===========未去重的数据============");
        System.out.println(numList.toString());
        System.out.println("===========去重后的数据============");
        List<String> collect = numList.stream().distinct().collect(Collectors.toList());
        System.out.println(collect.toString());

    }

8.1 List去重效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第9张图片

九、List的合并

首先了解下交集并集差集的概念
分别有三个区域A,B,C
JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第10张图片

9.1 List的合并之—>并集


    /**
     * 得到两个集合的并集
     */
    @Test
    public void listByJava8() {
        List<String> list1 = new ArrayList();
        list1.add("aaa");
        list1.add("bbb");
        list1.add("ccc");
        list1.add("aaa1");
        List<String> list2 = list1;
        list2.add("ddd");
        list2.add("aaa");
        list2.add("eee");
        list2.add("ccc");
        list2.add("fff");
        list2.add("aaa1");
        list2.add("aaa2");

        //根据整个对象是否一致来去重合并得到并集
        System.out.println("==========并集: 集合A{1, 2, 3} 和集合B {2, 3, 4} 的并集是 {1, 2, 3, 4}==========");
        System.out.println("---->并集写法一 [去重]");
        System.out.println("============并集举例一:根据List去重特性合并多个Lits============");
        List<String> collect = Stream.of(list1, list2).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        System.out.println(collect.toString());
        System.out.println("---->并集写法二 ");
        System.out.println("============并集举例二:根据List得到并集============");
        List<String> collect1 = list1.stream().filter(s -> list2.contains(s)).distinct().collect(Collectors.toList());
        System.out.println(collect1);
        System.out.println("==========交集: 集合A {1,2,3} 和集合B {2,3,4} 的交集为 {2,3}。即{1,2,3}∩{2,3,4}={2,3}==========");


    }

9.1.1 List的合并之—>并集效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第11张图片

9.2 List的合并之—>交集(即两个或多个list重复的元素的集合)

/**
     * 得到两个集合的交集
     */
    @Test
    public void listBingByJava8() {
        System.out.println("==========交集: 集合A {1,2,3} 和集合B {2,3,4} 的交集为 {2,3}。即{1,2,3}∩{2,3,4}={2,3}==========");
        List<String> list1 = new ArrayList();
        list1.add("aaa");
        list1.add("bbb");
        list1.add("ccc");
        list1.add("aaa1");
        List<String> list2 = list1;
        list2.add("ddd");
        list2.add("aaa");
        list2.add("eee");
        list2.add("ccc");
        list2.add("fff");
        list2.add("aaa1");
        list2.add("aaa2");
        //合并List
        List<String> collect = list1.stream().filter(s -> list2.contains(s)).collect(Collectors.toList());
        System.out.println("============多个List合并后的元数据===========");
        System.out.println(collect);
        // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
        List<String> collect1 = collect.stream().collect(Collectors.toMap(a -> a, a -> 1, (a, b) -> a + b))
                //  Set转换为Stream
                .entrySet().stream()
                // 过滤出元素出现次数大于 1 的 entry
                .filter(entry -> entry.getValue() > 1)
                // 获得 entry 的键(重复元素)对应的 Stream
                .map(entry -> entry.getKey())
                // 转化为 List并去重
                .distinct().collect(Collectors.toList());
        System.out.println("========合并后得到处理得到重复的数据========");
        System.out.println(collect1);
    }

9.2.1 List的合并之—>交集效果图

JAVA8中Stream的用法之最大、最小、平均值、分组、求和、遍历、过滤、排序_第12张图片

你可能感兴趣的:(java)