java8之lambda表达式的23种使用总结

本文详细介绍了Java 8的Stream API在处理集合时的各种操作,包括遍历、属性筛选、类型转换、分组、求和、求最小值、过滤、排序等。通过实例展示了如何高效地对 Employee 对象集合进行操作,如提取特定属性、按属性分组求和、去重等,揭示了Stream API的强大功能。
摘要由CSDN通过智能技术生成
package com.lyc.collections;

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

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * lambda表达式测试
 *
 * @author lyc
 * @date 2021/8/5
 */
public class LycLambdaCollections {

    /**
     * 1、遍历list集合
     *
     * @param list
     */
    public static void foreachColl(List<Employee> list) {
        System.out.println("--------------------------------------------------------------");
        list.forEach(employee -> {
            System.out.println(employee.toString());
        });
    }

    /**
     * 2、获取集合中对象的某一个属性的集合
     */
    public static void getOnlyIdList(List<Employee> list) {
        System.out.println("getOnlyIdList result===========================");
        List<Long> idList = list.stream().map(employee -> employee.getId()).collect(Collectors.toList());
        System.out.println("firstMethod employee -> employee.getId():");
        System.out.println(idList.toString());
        System.out.println("");
        System.out.println("secondMethod Employee::getId:");
        List<Long> idListTwo = list.stream().map(Employee::getId).collect(Collectors.toList());
        System.out.println(idListTwo);
    }

    /**
     * 3、获取集合中对象的某一个属性的集合并对属性做类型转换
     *
     * @param list
     */
    public static void getOneFiledWithDeal(List<Employee> list) {
        List<Long> deptNoList = list.stream().map(employee -> employee.getDeptNo()).map(Long::valueOf).collect(Collectors.toList());
        System.out.println(deptNoList.toString());
    }

    /**
     * 4、将数组元素做其他处理后转成list集合
     *
     * @param list
     */
    public static void getOneFiledFromArray(List<Employee> list) {
        List<String> nameList = list.stream().map(employee -> employee.getName()).collect(Collectors.toList());
        String str = String.join(",", nameList);
        List<String> upperNameList = Arrays.stream(str.split(",")).map(String::toUpperCase).collect(Collectors.toList());
        System.out.println(upperNameList.toString());
    }

    /**
     * 5、将集合对象按<集合中对象的某个属性、对象本身>转成map----->简单分组,key为对象一个属性值,值为对象本身
     *
     * @param list
     */
    public static void groupByIdForObjectMap(List<Employee> list) {
        Map<Long, Employee> map = list.stream().collect(Collectors.toMap(Employee::getId, employee -> employee));
        System.out.println(map);
    }

    /**
     * 6、将集合对象按<集合中对象的某个属性、集合中对象的另一个个属性>转map----->简单分组2,key为对象一个属性值,值为对象的某一个属性值
     *
     * @param list
     */
    public static void groupByIdForOneFiledMap(List<Employee> list) {
        Map<Long, String> map = list.stream().collect(Collectors.toMap(Employee::getId, Employee::getName));
        System.out.println(map);
    }

    /**
     * 7、将集合对象按<集合中对象的某个属性、集合中对象的另一个个属性>转map----->简单分组3,key为对象一个属性值,值为对象的某一个属性值
     * (这种场景存在key重复的需要指定用哪个覆盖哪个)
     *
     * @param list
     */
    public static void groupByRepeatNameForOneFiledMap(List<Employee> list) {
        // 保留前面的元素
        Map<String, Long> map1 = list.stream().collect(Collectors.toMap(Employee::getName, Employee::getId, (k1, k2) -> k1));
        System.out.println(map1);

        // 用后面的元素覆盖
        Map<String, Long> map2 = list.stream().collect(Collectors.toMap(Employee::getName, Employee::getId, (k1, k2) -> k2));
        System.out.println(map2);
    }

    /**
     * 8、将集合对象按<对象的某个属性、List<对象本身>>转map------>复杂分组,key为对象一个属性值,值为对象集合
     *
     * @param list
     */
    public static void groupByIdForListObjectMap(List<Employee> list) {
        Map<String, List<Employee>> map = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo));
        System.out.println(map);
    }

    /**
     * 9、将集合对象按<对象的某个属性、List<对象的某个属性>>转map------>复杂分组2,key为对象一个属性值,值为对象的一个属性值集合
     *
     * @param list
     */
    public static void groupByIdForOneFiledListMap(List<Employee> list) {
        Map<String, List<Long>> map = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.mapping(Employee::getId, Collectors.toList())));
        System.out.println(map);
    }

    /**
     * 10、将集合对象按<对象的某个属性、List<对象的某个属性>>转map------>复杂分组3,key为对象一个属性值,值为对象的一个属性值集合
     * (这个写法需要保证key唯一,使用场景是将唯一key的对象其他多个属性合并为集合)
     *
     * @param list
     */
    public static void groupByIdForManyFiledListMap(List<Employee> list) {
        Map<Long, List<Long>> map = list.stream().collect(Collectors.toMap(Employee::getId, employee -> Arrays.asList(employee.getId(), 2L)));
        System.out.println(map);
    }

    /**
     * 11、求所有的薪资总和,返回一个值------>求和
     *
     * @param list
     */
    public static void sumAll(List<Employee> list) {
        // 先将list转成stream流
        // 获取salary
        // 自定义计算salary总和
        // 第一个参数表示求和的初始值、第二个参数表示上一步求和的中间值以及本次要计算的值(subNum,salary) 实现就是将求和的中间值与本次的值相加
        Long totalSum = list.stream().map(Employee::getSalary).reduce(0L, (subNum, salary) -> (subNum + salary));
        System.out.println(totalSum);

        Long totalSum2 = list.stream().map(Employee::getSalary).reduce(0L, Long::sum);
        System.out.println(totalSum2);

        Long totalSum3 = list.stream().mapToLong(Employee::getSalary).sum();
        System.out.println(totalSum3);

        // 测试备份下BigDecimal类型的求和
        BigDecimal totalQty = list.stream().map(p -> p.getTestQty().multiply(p.getTestQty())).reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println(totalSum3);
    }

    /**
     * 12、将集合中的对象按某个属性分组,并对每个分组中对象的另一个属性求和------>分组并求和
     *
     * @param list
     */
    public static void sumGroupById(List<Employee> list) {
        Map<String, LongSummaryStatistics> map = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.summarizingLong(Employee::getSalary)));
        System.out.println(map);

        Map<String, Long> map2 = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.summingLong(Employee::getSalary)));
        System.out.println(map2);

        Map<String, Long> map3 = list.stream().collect(Collectors.groupingBy(Employee::getDeptNo, Collectors.reducing(0L, Employee::getSalary, Long::sum)));
        System.out.println(map3);
    }

    /**
     * 13、求集合中的对象按某个属性最小值------>求最小值
     *
     * @param list
     */
    public static void minAll(List<Employee> list) {
        Long min = list.stream().mapToLong(Employee::getSalary).min().getAsLong();
        System.out.println(min);

        Long min2 = list.stream().min(Comparator.comparing(Employee::getSalary)).get().getSalary();
        System.out.println(min2);

        Long min3 = list.stream().collect(Collectors.minBy(Comparator.comparing(Employee::getSalary))).get().getSalary();
        System.out.println(min3);
    }

    /**
     * 14、将集合中的对象按某个属性分组,并对每个分组中对象的另一个属性求最小值------>分组并求最小值
     *
     * @param list
     */
    public static void minGroupBy(List<Employee> list) {
        Map<String, Employee> map = list.stream()
                .collect(Collectors.toMap(Employee::getDeptNo, Function.identity(), BinaryOperator.minBy(Comparator.comparing(Employee::getSalary))));
        System.out.println(map);
    }

    /**
     * 15、将集合中的对象按多个条件过滤,返回过滤后的对象集合------>多条件过滤
     * 年龄小于30且薪资大于6000的
     *
     * @param list
     */
    public static void filterByCondition(List<Employee> list) {
        list = list.stream().filter(employee -> employee.getAge() < 30 && employee.getSalary() > 6000).collect(Collectors.toList());
        foreachColl(list);
    }

    /**
     * 16、按一个条件正序排列------>正序排
     * 按年龄从小到达排序
     *
     * @param list
     */
    public static void sortOneConditionNature(List<Employee> list) {
        List<Employee> list1 = list.stream().sorted((o1, o2) -> o1.getAge() - o2.getAge()).collect(Collectors.toList());
        foreachColl(list1);

        List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge)).collect(Collectors.toList());
        foreachColl(list2);
    }

    /**
     * 17、按多个条件都正序排列------>正序正序排 【两个都正不加reversed()】
     * 按年龄从小到达排序,再按薪水从小到大排序
     *
     * @param list
     */
    public static void sortTwoConditionAllNature(List<Employee> list) {
        List<Employee> list1 = list.stream().sorted((o1, o2) -> {
            int flag = o1.getAge() - o2.getAge();
            if (flag == 0) {
                flag = (int) (o1.getSalary() - o2.getSalary());
            }
            return flag;
        }).collect(Collectors.toList());
        foreachColl(list1);

        List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge).thenComparing(Employee::getSalary)).collect(Collectors.toList());
        foreachColl(list2);
    }

    /**
     * 18、按一个条件倒序排列----->倒序排
     * 按年龄从大到小排序
     *
     * @param list
     */
    public static void sortOneConditionReverse(List<Employee> list) {
        List<Employee> list1 = list.stream().sorted((o1, o2) -> o2.getAge() - o1.getAge()).collect(Collectors.toList());
        foreachColl(list1);

        List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge,Comparator.reverseOrder())).collect(Collectors.toList());
        foreachColl(list2);

        List<Employee> list3 = list.stream().sorted(Comparator.comparing(Employee::getAge).reversed()).collect(Collectors.toList());
        foreachColl(list3);
    }

    /**
     * 19、按多个条件都倒序排列---->倒序倒序排 【两个都倒序在最后面加一个reversed()即可】
     * 按年龄从大到小排序,再按薪水从大到小排
     *
     * @param list
     */
    public static void sortTwoConditionAllReverse(List<Employee> list) {
        List<Employee> list1 = list.stream().sorted((o1, o2) -> {
            int flag = o2.getAge() - o1.getAge();
            if (flag == 0) {
                flag = (int) (o2.getSalary() - o1.getSalary());
            }
            return flag;
        }).collect(Collectors.toList());
        foreachColl(list1);


        List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge, Comparator.reverseOrder()).thenComparing(Employee::getSalary, Comparator.reverseOrder()))
                .collect(Collectors.toList());
        foreachColl(list2);

        List<Employee> list3 = list.stream().sorted(Comparator.comparing(Employee::getAge).thenComparing(Employee::getSalary).reversed()).collect(Collectors.toList());
        foreachColl(list3);


    }

    /**
     * 20、按多个条件先正序排再倒序排---->先正序后倒序【先正加reversed(),后倒加reversed()】
     * 按年龄从小到大,再按薪水从大到小排序
     *
     * @param list
     */
    public static void sortTwoConditionOneNatureOneReverse(List<Employee> list) {
        List<Employee> list1 = list.stream().sorted(Comparator.comparing(Employee::getAge).thenComparing(Employee::getSalary,Comparator.reverseOrder())).collect(Collectors.toList());
        foreachColl(list1);

        List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge).reversed().thenComparing(Employee::getSalary).reversed()).collect(Collectors.toList());
        foreachColl(list2);
    }

    /**
     * 21、按多个条件先倒序排再正序排---->先倒序后正序【先倒序的加reserved(),后正序的不加】
     * 按年龄从大到小,再按薪水从小到大排序
     *
     * @param list
     */
    public static void sortTwoConditionOneReverseOneNature(List<Employee> list) {
        List<Employee> list1 = list.stream().sorted(Comparator.comparing(Employee::getAge,Comparator.reverseOrder()).thenComparing(Employee::getSalary)).collect(Collectors.toList());
        foreachColl(list1);

        List<Employee> list2 = list.stream().sorted(Comparator.comparing(Employee::getAge).reversed().thenComparing(Employee::getSalary)).collect(Collectors.toList());
        foreachColl(list2);
    }

    /**
     * 22、取集合元素的某几个值去重后转集合----->抽取对象多个值转集合去重
     * 求所有人的地址集合,去重
     *
     * @param list
     */
    public static void getMultiToSet(List<Employee> list) {
        List<String> list1 = list.stream().flatMap(e -> Stream.of(e.getFmAddress(), e.getToAddress())).distinct().collect(Collectors.toList());
        System.out.println(list1);
    }

    /**
     * 23、根据集合元素的某些信息组装新对象---->对象A组装对象B返回
     * 抽取用户ID、姓名、部门信息返回简单对象DTO
     *
     * @param list
     */
    public static void getNewList(List<Employee> list) {
        List<SimpleEmpDto> list1 = list.stream().map(e -> {
            SimpleEmpDto dto = new SimpleEmpDto();
            dto.setId(e.getId());
            dto.setName(e.getName());
            dto.setDeptNo(e.getDeptNo());
            return dto;
        }).collect(Collectors.toList());
        list1.forEach(dto -> System.out.println(dto));
    }

	public static void main(String[] args) {
        List<Employee> list = EmployeeFactory.buildEmployByChain();
        foreachColl(list);
        //getOnlyIdList(list);
        //getOneFiledWithDeal(list);
        //getOneFiledFromArray(list);
        //groupByIdForObjectMap(list);
        //groupByIdForOneFiledMap(list);
        //groupByRepeatNameForOneFiledMap(list);
        //groupByIdForListObjectMap(list);
        //groupByIdForOneFiledListMap(list);
        //groupByIdForManyFiledListMap(list);
        //sumAll(list);
        //sumGroupById(list);
        //minAll(list);
        //minGroupBy(list);
        //filterByCondition(list);
        //sortOneConditionNature(list);
        //sortTwoConditionAllNature(list);
        //sortOneConditionReverse(list);
        //sortTwoConditionAllReverse(list);
        //sortTwoConditionOneNatureOneReverse(list);
        //sortTwoConditionOneReverseOneNature(list);
        //getMultiToSet(list);
        //getNewList(list);
    }

}



/**
 * 雇员Bean
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Employee implements Serializable {
    private static final long serialVersionUID = -3966543324371928911L;

    /**
     * 编号
     */
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 薪水
     */
    private Long salary;

    /**
     * 生日
     */
    private Date birthday;

    /**
     * 爱好
     */
    private List<String> favorites;

    /**
     * 所属部门编号(数字类型的)
     */
    private String deptNo;

    /**
     * 从哪来
     */
    private String fmAddress;

    /**
     * 到哪去
     */
    private String toAddress;

    /**
     * 测试BigDecimal类型的属性计算
     */
    private BigDecimal testQty;

    @Override
    public String toString() {
        return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", salary=" + salary + ", birthday="
                + (null == birthday ? "" : DateUtils.formatToStringDefault(birthday)) + ", favorites=" + favorites + ", deptNo='" + deptNo + '\'' + '}';
    }
}


/**
 * 简单雇员Bean
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class SimpleEmpDto implements Serializable {
    private static final long serialVersionUID = 8479182105142615840L;

    /**
     * 编号
     */
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 所属部门编号(数字类型的)
     */
    private String deptNo;

    @Override
    public String toString() {
        return "SimpleEmpDto{" + "id=" + id + ", name='" + name + '\'' + ", deptNo='" + deptNo + '\'' + '}';
    }
}


/**
 * 构建测试数据
 */
class EmployeeFactory {
    public static List<Employee> buildEmployByChain(){
        List<Employee> list = new ArrayList<Employee>();
        list.add(Employee.builder().id(1L).name("yangsan").age(20).salary(3000L)
                .birthday(DateUtils.parseToDate("2001-01-01",DateUtils.single_format))
                .deptNo("1").favorites(Arrays.asList("film","music")).fmAddress("中国").toAddress("中国").build());

        list.add(Employee.builder().id(2L).name("lisi").age(18).salary(3000L)
                .birthday(DateUtils.parseToDate("2003-01-01",DateUtils.single_format))
                .deptNo("3").favorites(Arrays.asList("play","music")).fmAddress("中国").toAddress("美国").build());

        list.add(Employee.builder().id(3L).name("wangwu").age(45).salary(7000L)
                .birthday(DateUtils.parseToDate("1976-01-01",DateUtils.single_format))
                .deptNo("2").favorites(Arrays.asList("swim","sing")).fmAddress("法国").toAddress("意大利").build());

        list.add(Employee.builder().id(4L).name("huangbo").age(30).salary(5000L)
                .birthday(DateUtils.parseToDate("1991-01-01",DateUtils.single_format))
                .deptNo("3").favorites(Arrays.asList("running","read")).fmAddress("日本").toAddress("韩国").build());

        list.add(Employee.builder().id(5L).name("yilong").age(25).salary(4000L)
                .birthday(DateUtils.parseToDate("1996-01-01",DateUtils.single_format))
                .deptNo("1").favorites(Arrays.asList("bike","code")).fmAddress("朝鲜").toAddress("中国").build());

        list.add(Employee.builder().id(6L).name("xiayu").age(34).salary(5500L)
                .birthday(DateUtils.parseToDate("1987-01-01",DateUtils.single_format))
                .deptNo("3").favorites(Arrays.asList("game","music")).fmAddress("巴基斯坦").toAddress("中国").build());

        list.add(Employee.builder().id(7L).name("yangsanqi").age(29).salary(8000L)
                .birthday(DateUtils.parseToDate("1992-01-01",DateUtils.single_format))
                .deptNo("1").favorites(Arrays.asList("shopping","music")).fmAddress("中国").toAddress("英国").build());

        list.add(Employee.builder().id(8L).name("yangsanba").age(18).salary(2000L)
                .birthday(DateUtils.parseToDate("2003-01-01",DateUtils.single_format))
                .deptNo("1").favorites(Arrays.asList("eating","music")).fmAddress("俄罗斯").toAddress("法国").build());
        return list;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值