Predicate-代码简洁之道
Predicate是Java 8增加的特性,中文翻译为(谓词;使基于,使取决于;表明,断言)。中文意思应该是,“因为今天刮台风,所以小明不用去上学”。这句话中的原因,即Predicate=原因(条件)。
任何代码逻辑都少不了IF
判断(或Switch
、For
等),为了写出更简洁明了的代码,便可以将这些判断中的条件抽象成Predicate
,Predicate
的输出结果只有TRUE
和FALSE
两种。
例如:
1 2 3
| Predicate<Long> isEvent = hours -> (hours > 24 && hours < 24 * 3); isEvent.test(20L);
|
我们也知道,在Java 8 的特性中,有着另一种用于处理空指针异常的方式:Optional
,它也是一种判断条件的抽象表示,更适用于null
值的处理操作,经常在代码行内使用,例如:
1 2 3 4 5
| public void test(List<Long> list){ List<Long> longs = Optional.of(list).orElse(new ArrayList<>()); longs.add(1L); System.out.println(longs); }
|
而Predicate
经常会当做一个方法的参数进行传递,例如:账号过期提醒规则,剩余1个月有效期则每周提醒一次,剩余7天内有效期则每天提醒一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public void userTask{ @Autowired private UserService userService; @Scheduled(cron = "0 0 3 * * ?") public void dayInform() { Predicate<Long> event= hours -> (hours > 8 && hours < 24 * 7); checkAccountEffective(isEvent, "每天定时提醒"); }
@Scheduled(cron = "0 0 3 ? * 1") public void weekInform() { Predicate<Long> event= hours -> (hours > 24 * 7 && hours < 24 * 30); checkEffectiveTime(event, "每周定时提醒"); } private void checkEffectiveTime(Predicate<Long> event, String task) { List<User> users = userService.list(); List<MessageSend> messages = new ArrayList<>(); LocalDateTime now = LocalDateTime.now(); users.forEach(user -> { LocalDateTime expiryTime = user.getExpiryTime(); if (expiryTime == null || now.isAfter(expiryTime)) { return; } long hours = Duration.between(now, expiryTime).toHours(); if (event.test(hours)) { String message = "尊敬的用户,您的账号将在%s到期,请及时处理。"; MessageSend msg= MessageSend(message.formatted(expiryDate.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))), user.getId(),task); messages.add(msg); } }); userService.sendMessage(messages); } }
|
上面的代码,便是将IF
判断条件抽象成Preditace
,避免了编写重复代码。