实际工作中解决空指针的Option记录
原因: 空指针真他妈操蛋,公司的数据库更操蛋,又空指针,还有这样的值''
,你们想想我心里的一万匹草泥马.
需求: 需要向employee对象里设置一个从数据库里查询的值(查询出这个值所需的条件也是从数据库里查询出来的,不要吐槽数据库,不是俺设计的.里面就有 ''
这样的值!同时也又正常的空指针,就是不设置默认值,嘿嘿)
代码:
@RunWith(Parameterized.class)
public class ServiceTest {
private String time = "2017-07-13";//查询条件的部分
private int days = 10;//查询出来的天数,从子数据库
DepartmentCostExtensive employee = new DepartmentCostExtensive();
@Parameter
public String stratTime;
@Parameter(1)
public String endTime;
@Parameter(2)
public String startDays;
@Parameter(3)
public String endDays;
public static final String[][] datas = {
{"2017-06-13", "2017-08-13", "10", "10"},
{"2017-07-10", "2017-08-13", "0", "10"},
{"2017-06-13", "2017-07-15", "10", "0"},
{"2017-07-10", "2017-07-15", "0", "0"}
};
@Parameters(name = "{index}->{0} to {1} beforeDays:{2},afterDays:{3}")
public static Iterable<String[]> assign() {
return Arrays.asList(datas);
}
@Test
public void test() {
//虚拟构造level
Level level = new Level();
level.setStartRenderTime(Date.valueOf(LocalDate.parse(stratTime)));
level.setEndRenderTime(Date.valueOf(LocalDate.parse(endTime)));
level.setInCoefficient("1.0");
level.setExceedCoefficient("1.0");
Optional<Date> startRenderTime = Optional.ofNullable(level.getStartRenderTime());
Optional<Date> endRenderTime = Optional.ofNullable(level.getEndRenderTime());
BiConsumer<Boolean, Integer> beforeConsumer = (Boolean flag, Integer value) -> {
if (flag)
employee.setBeforeRender(value);
};
BiConsumer<Boolean, Integer> afterConsumer = (Boolean flag, Integer value) -> {
if (flag)
employee.setAfterRender(value);
};
beforeConsumer.accept(startRenderTime.map(date -> isBefore(date)).orElse(false), days);
afterConsumer.accept(endRenderTime.map(date -> isAfter(date)).orElse(false), days);
assertThat(employee.getBeforeRender() + "", is(startDays));
assertThat(employee.getAfterRender() + "", is(endDays));
}
private boolean isBefore(Date date) {
return date.toLocalDate().isBefore(LocalDate.parse(time).with(TemporalAdjusters.firstDayOfMonth()));
}
private boolean isAfter(Date date) {
return date.toLocalDate().isAfter(LocalDate.parse(time).with(TemporalAdjusters.lastDayOfMonth()));
}
}
分析: 上面代码已经很详细了,关键是思路,level里面的参数startRenderTime和endRenderTime是我下面要查询的days数据的查询条件,但是它需要被各种转换(这个我也很无奈,数据库不是我设计的),因此必须保证它正确才能正常的执行,不喜欢写xxx!=null这样的语句,这里我们用option来解决这个问题,用optition来包装level出来需要的对象,然后用consumer来执行不同的行为.如果田间判断为真,就执行(这里可以看出我们的查询条件是2017-07-13,startTime为2017-06-13的时候,比2017-07-01前面,故执行操作,插入天数10;同理endTime为2017-07-15的时候,比2017-07-31前面,因此不执行操作,采用默认值)
求解:
- 求能把这两个consumer和判断predicate能一次性合起来又简单的方法!
- 这种的单元测试能不能不让要被注入的参数全是一种类型的,这里parameter(2)和parameter(3)写不成
int
||
Integer
类型的,谁能解决下请@373035580
.
用map方法来解决次问题:
//todo:先不更次部分,整体代码全部用函数式编程重构完一次再回来更新次部分,最好的方式当然是map方法了! //此次项目会整个加入分布式框架,监控,和用scala/Java分别写的大数据处理程序,分两种,一种是和web集成的(性能很低),另一种是单独的spark数据处理,从kafka读取并处理.然后借此机会把java9也跟新进去,刚出来的,哇咔咔,爽,写了java8以后不想用Java写代码了,目前脑子里全是函数式,各种想把一个项目用流式直接处理完的想法.