967°

lambda表达式分组,过滤,求和,最值,排序,去重

@[TOC]

简介

Java 8 新特性


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

实例

先准备个实体类

import java.math.BigDecimal;
import java.util.Date;
 
public class User {
 
    private long id;
 
    //姓名
    private String name;
 
    //年龄
    private int age;
 
    //工号
    private String jobNumber;
 
    //性别
    private int gender;
 
    //入职日期
    private Date entryDate;
 
    //钱
    private BigDecimal money;

    //省略get set
    ...
 
}

分组

通过groupingBy将集合分组拆分成多个集合

//通过年龄分组、得到一个以年龄为键,用户集合为值的Map集合
Map<Integer,List<User>> groupByAge = userList.stream().collect(Collectors.groupingBy(User::getAge));

过滤

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

//过滤
//排除掉工号为1001的用户
//filter内添加条件、保留返回true的实例
List<User> list = userList.stream().filter(user -> !user.getJobNumber().equals("1001")).collect(Collectors.toList());

求和

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

//求和
//基本类型
int sumAge = userList.stream().mapToInt(User::getAge).sum();
//BigDecimal求和
BigDecimal totalMoney= userList.stream().map(User::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);

注意:在上述BigDecimal类型求和中,如果对象为null则会抛出空指针异常

1、我们可以先试用filter方法进行过滤

//先过滤掉为null的
List<Usrt> list = userList.stream().filter(user -> null != user).collect(Collectors.toList());
//再求和
BigDecimal totalMoney = userList.stream().map(User::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add);

2、或者可以重写求和方法

package com.jamesluozhiwei.util;
 
import java.math.BigDecimal;
 
public class BigDecimalUtils {
 
 	/**
 	 * 如果为null就返回0
 	 * @param in
 	 * @return
 	 */
    public static BigDecimal ifNullSet0(BigDecimal in) {
        if (in != null) {
            return in;
        }
        return BigDecimal.ZERO;
    }
 
 	/**
 	 * 求和
 	 * @param in
 	 * @return
 	 */
    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 totalMoney = userList.stream().map(User::getMoney).reduce(BigDecimal.ZERO,BigDecimalUtils::sum);

最值

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

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

List转Map

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

排序

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

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

去重

通过distinct方法进行去重

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

获取list对象某个字段组装新的list

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

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

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

全部评论: 0

    我有话说: