一. 前期准备
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;
}