目录
- 一. 前期准备
- 1.1 各种实体类
- 1.2 生成`List<CommonUser>`的方法
- 1.3 需求
- 二. 难以阅读的Lambda表达式
- 三. 干净的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;
}