Java 干净的Stream,Lambda代码写法


一. 前期准备

1.1 各种实体类

⏹Address实体类,用来存储地址

import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
public class Address {

    private String province;

    private String city;

    private String home;
}

⏹CommonUser 实体类,用来存放普通用户的信息

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Builder
@Getter
@Setter
public class CommonUser {

    private String name;

    private Integer gender;

    private Integer age;
	
	// 一个用户可能有多个地址
    private List<Address> addressList;
}

⏹SimpleUser 实体类,用来存放精简之后的用户信息

import lombok.Data;

@Data
public class SimpleUser {

    private String name;

    private Integer age;

    private String province;
}

1.2 生成List<CommonUser>的方法

private List<CommonUser> createCommonUserList() {

    List<Address> addressList1 = Arrays.asList(
            Address.builder().province("山东省").city("聊城市").home("村1").build(),
            Address.builder().province("山西省").city("X城市").home("村2").build()
    );
    CommonUser commonUser1 = CommonUser.builder().name("张三").gender(1).age(18).addressList(addressList1).build();
    
    List<Address> addressList2 = Arrays.asList(
            Address.builder().province("河南省").city("濮阳市").home("村3").build(),
            Address.builder().province("河北省").city("Y城市").home("村4").build()
    );
    CommonUser commonUser2 = CommonUser.builder().name("李四").gender(2).age(19).addressList(addressList2).build();
    
    List<Address> addressList3 = Arrays.asList(
            Address.builder().province("海南省").city("海口市").home("村5").build(),
            Address.builder().province("海北省").city("Z城市").home("村6").build()
    );
    CommonUser commonUser3 = CommonUser.builder().name("王五").gender(1).age(34).addressList(addressList3).build();
    
    List<Address> addressList4 = Arrays.asList(
            Address.builder().province("东北省").city("沈阳市").home("村7").build(),
            Address.builder().province("东南省").city("U城市").home("村8").build()
    );
    CommonUser commonUser4 = CommonUser.builder().name("赵六").gender(1).age(26).addressList(addressList4).build();

    return Arrays.asList(commonUser1, commonUser2, commonUser3, commonUser4);
}

1.3 需求

⏹内容
从存放CommonUser实体类的List中过滤出性别为1,且 45 >= 年龄 >= 19 的用户,并将姓名,年龄,第一个地址的省份等信息放入SimpleUser实体类中,返回一个新List。


二. 难以阅读的Lambda表达式

  • 核心处理就只是 .stream().filter().map().sorted().collect()
  • 整个代码中充满了各种 ->和花括号。
  • 各种业务处理逻辑和.filter().map()混杂在一起,显得臃肿,不宜阅读。
  • 如果之后业务发生了变更,乍一看不知道从何着手。
private List<SimpleUser> dirtyLambda(List<CommonUser> commonUserList) {

    List<SimpleUser> simpleUserList = commonUserList.stream().filter(user -> {
        return user.getGender().equals(1)
                && user.getAge() >= 19 && user.getAge() <= 40;
    }).map(user -> {
    
        SimpleUser simpleUser = new SimpleUser();
        simpleUser.setName(user.getName());
        simpleUser.setAge(user.getAge());

        Optional<Address> optionalAddress = user.getAddressList().stream().findFirst();
        if (optionalAddress.isPresent()) {
            simpleUser.setProvince(optionalAddress.get().getProvince());
        }

        return simpleUser;
    }).sorted(Comparator.comparingInt(SimpleUser::getAge))
      .collect(Collectors.toList());
      
    return simpleUserList;
}

三. 干净的Lambda表达式

  • 可以看到在cleanLambda方法中的主干结构很清楚。
  • .filter().map()中所设计的业务处理都被抽取出来。
  • 整个代码中没有 箭头->花括号{}
  • .filter()相关的业务处理除了可以抽取为静态方法外,还可以抽取成谓词
// 根据性别和年龄过滤用户
private static boolean filterUser(CommonUser user) {
    return user.getGender().equals(1) && user.getAge() >= 19 && user.getAge() <= 40;
}

// 将CommonUser中的内容抽取到SimpleUser中
private static SimpleUser getSimpleUser(CommonUser user) {

    SimpleUser simpleUser = new SimpleUser();
    simpleUser.setName(user.getName());
    simpleUser.setAge(user.getAge());

    // Optional的IF判断的简化写法
    Optional<Address> optionalAddress = user.getAddressList().stream().findFirst();
    optionalAddress.ifPresent(address -> simpleUser.setProvince(address.getProvince()));

    return simpleUser;
}

// 干净的Lambda表达式
private List<SimpleUser> cleanLambda(List<CommonUser> commonUserList) {

    // 也可以将过滤条件抽取为【谓词】
    Predicate<CommonUser> filterUser = user -> user.getGender().equals(1) && user.getAge() >= 19 && user.getAge() <= 40;

    List<SimpleUser> simpleUserList = commonUserList.stream()
            // 使用静态方法进行过滤
            .filter(JmwApplication::filterUser)
            // 也可以使用谓词进行过滤 😒※此处只是为了展示谓词的用法
            .filter(filterUser)
            .map(JmwApplication::getSimpleUser)
            // 根据年龄进行排序
            .sorted(Comparator.comparingInt(SimpleUser::getAge))
            // 收集为List
            .collect(Collectors.toList());

    return simpleUserList;
}

四. 效果

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值