zoukankan      html  css  js  c++  java
  • java8的lambda表达式

    转自:https://blog.csdn.net/gsls200808/article/details/86501905

    java8的lambda表达式提供了一些方便list操作的方法,主要涵盖分组、过滤、求和、最值、排序、去重。跟之前的传统写法对比,能少写不少代码。

    新建实体类

     
    package com.vvvtimes.vo;
     
     
     
    import java.math.BigDecimal;
     
    import java.util.Date;
     
     
     
    public class User {
     
     
     
    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;
     
    }
     
    }

    1.分组

    通过groupingBy可以分组指定字段

    1.  
      //分组
    2.  
      Map<String, List<User>> groupBySex = userList.stream().collect(Collectors.groupingBy(User::getSex));
    3.  
      //遍历分组
    4.  
      for (Map.Entry<String, List<User>> entryUser : groupBySex.entrySet()) {
    5.  
      String key = entryUser.getKey();
    6.  
      List<User> entryUserList = entryUser.getValue();
    7.  
      }

    多字段分组

    1.  
      Function<WarehouseReceiptLineBatch, List<Object>> compositeKey = wlb ->
    2.  
      Arrays.<Object>asList(wlb.getWarehouseReceiptLineId(), wlb.getWarehouseAreaId(), wlb.getWarehouseLocationId());
    3.  
      Map<Object, List<WarehouseReceiptLineBatch>> map =
    4.  
      warehouseReceiptLineBatchList.stream().collect(Collectors.groupingBy(compositeKey, Collectors.toList()));
    5.  
      //遍历分组
    6.  
      for (Map.Entry<Object, List<WarehouseReceiptLineBatch>> entryUser : map.entrySet()) {
    7.  
      List<Object> key = (List<Object>) entryUser.getKey();
    8.  
      List<WarehouseReceiptLineBatch> entryUserList = entryUser.getValue();
    9.  
      Long warehouseReceiptLineId = (Long) key.get(0);
    10.  
      Long warehouseAreaId = (Long) key.get(0);
    11.  
      Long warehouseLocationId = (Long) key.get(0);
    12.  
       
    13.  
      }

    2.过滤

    通过filter方法可以过滤某些条件

    1.  
      //过滤
    2.  
      //排除掉工号为201901的用户
    3.  
      List<User> userCommonList = userList.stream().filter(a -> !a.getJobNumber().equals("201901")).collect(Collectors.toList());

    3.求和

    分基本类型和大数类型求和,基本类型先mapToInt,然后调用sum方法,大数类型使用reduce调用BigDecimal::add方法

    1.  
      //求和
    2.  
      //基本类型
    3.  
      int sumAge = userList.stream().mapToInt(User::getAge).sum();
    4.  
      //BigDecimal求和
    5.  
      BigDecimal totalQuantity = userList.stream().map(User::getFamilyMemberQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);

    上面的求和不能过滤bigDecimal对象为null的情况,可能会报空指针,这种情况,我们可以用filter方法过滤,或者重写求和方法

    重写求和方法

      

    package com.vvvtimes.util;
     
     
     
    import java.math.BigDecimal;
     
     
     
    public class BigDecimalUtils {
     
     
     
    public static BigDecimal ifNullSet0(BigDecimal in) {
     
    if (in != null) {
     
    return in;
     
    }
     
    return BigDecimal.ZERO;
     
    }
     
     
     
    public static BigDecimal sum(BigDecimal ...in){
     
    BigDecimal result = BigDecimal.ZERO;
     
    for (int i = 0; i < in.length; i++){
     
    result = result.add(ifNullSet0(in[i]));
     
    }
     
    return result;
     
    }
     
    }

    使用重写的方法

    BigDecimal totalQuantity2 = userList.stream().map(User::getFamilyMemberQuantity).reduce(BigDecimal.ZERO, BigDecimalUtils::sum);
    

    判断对象空

    stream.filter(x -> x!=null)
    stream.filter(Objects::nonNull)

    判断字段空

    stream.filter(x -> x.getDateTime()!=null)

    4.最值

    求最小与最大,使用min max方法

    1.  
      //最小
    2.  
      Date minEntryDate = userList.stream().map(User::getEntryDate).min(Date::compareTo).get();
    3.  
       
    4.  
      //最大
    5.  
      Date maxEntryDate = userList.stream().map(User::getEntryDate).max(Date::compareTo).get();

    有时候我们需要知道最大最小对应的这个对象,我们可以通过如下方法获取

    1.  
      Comparator<LeasingBusinessContract> comparator = Comparator.comparing(LeasingBusinessContract::getLeaseEndDate);
    2.  
      LeasingBusinessContract maxObject = leasingBusinessContractList.stream().max(comparator).get();

    5.List 转map

    1.  
      /**
    2.  
      * List -> Map
    3.  
      * 需要注意的是:
    4.  
      * toMap 如果集合对象有重复的key,会报错Duplicate key ....
    5.  
      * user1,user2的id都为1。
    6.  
      * 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
    7.  
      */
    8.  
      Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, a -> a,(k1,k2)->k1));

    list转map的时候有时候会将date类型作为key,实际情况中使用string的多,我们可以将某个字段转成string

    Map<String, WorkCenterLoadVo> workCenterMap = list.stream().collect(Collectors.toMap(key->DateFormatUtils.format(key.getDate(), "yyyy-MM-dd"), a -> a,(k1,k2)->k1));

    6.排序

    可通过Sort对单字段多字段排序

    1.  
      //排序
    2.  
      //单字段排序,根据id排序
    3.  
      userList.sort(Comparator.comparing(User::getId));
    4.  
      //多字段排序,根据id,年龄排序
    5.  
      userList.sort(Comparator.comparing(User::getId).thenComparing(User::getAge));

    7.去重

    可通过distinct方法进行去重

    1.  
      //去重
    2.  
      List<Long> idList = new ArrayList<Long>();
    3.  
      idList.add(1L);
    4.  
      idList.add(1L);
    5.  
      idList.add(2L);
    6.  
      List<Long> distinctIdList = idList.stream().distinct().collect(Collectors.toList());

    针对属性去重

    1.  
      List<AddOutboundNoticeDetailsBatchVo> entryDetailsBatchDistinctBatchIdList = entryDetailsBatchList.stream().filter(distinctByKey(b -> b.getMaterialBatchNumberId())).collect(Collectors.toList());
    2.  
       
    3.  
      //distinctByKey自己定义
    4.  
      public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
    5.  
      Map<Object, Boolean> seen = new ConcurrentHashMap<>();
    6.  
      return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    7.  
      }

    8.获取list某个字段组装新list

    1.  
      //获取list对象的某个字段组装成新list
    2.  
      List<Long> userIdList = userList.stream().map(a -> a.getId()).collect(Collectors.toList());

    9.批量设置list列表字段为同一个值

    addList.stream().forEach(a -> a.setDelFlag("0"));

    10.不同实体的list拷贝

    List<TimePeriodDate> timePeriodDateList1 = calendarModelVoList.stream().map(p->{TimePeriodDate e = new TimePeriodDate(); e.setStartDate(p.getBegin());e.setEndDate(p.getEnd()); return e;}).collect(Collectors.toList());
                           
  • 相关阅读:
    声明
    Random类——获取随机数
    JDK_API的使用方法
    Ajax?有谁开始学习了吗?
    用xslt循环xml同一节点的不同子节点
    在Repeater控件中嵌套一个Repeater控件
    html+css的一些技巧.收集中...
    记录一下: onbeforeunload()方法, 避免未保存而关闭页面.
    简单的C# Socket编程
    不实用的UriBuilder类
  • 原文地址:https://www.cnblogs.com/shipengda/p/14025055.html
Copyright © 2011-2022 走看看