1.利用 Optional
在 Java 8 里,引入了一个 Optional 类,该类是一个可以为 null 的容器对象。
1.1.保证值存在
构造方法,可以简化对象的初始化和设置属性操作。对于属性字段较少的类,可以自定义构造方法。
普通:
Integer thisValue;
if (Objects.nonNull(value)) {
thisValue = value;
} else {
thisValue = DEFAULT_VALUE;
}
精简:
Integer thisValue = Optional.ofNullable(value).orElse(DEFAULT_VALUE);
1.2 保证值合法
普通:
Integer thisValue;
if (Objects.nonNull(value) && value.compareTo(MAX_VALUE) <= 0) {
thisValue = value;
} else {
thisValue = MAX_VALUE;
}
精简:
Integer thisValue = Optional.ofNullable(value)
.filter(tempValue -> tempValue.compareTo(MAX_VALUE) <= 0).orElse(MAX_VALUE);
1.3 保证值合法
普通:
String zipcode = null;
if (Objects.nonNull(user)) {
Address address = user.getAddress();
if (Objects.nonNull(address)) {
Country country = address.getCountry();
if (Objects.nonNull(country)) {
zipcode = country.getZipcode();
}
}
}
精简:
tring zipcode = Optional.ofNullable(user).map(User::getAddress)
.map(Address::getCountry).map(Country::getZipcode).orElse(null);
2.利用 Stream
流(Stream)是Java 8的新成员,允许你以声明式处理数据集合,可以看成为一个遍历数据集的高级迭代器。流主要有三部分构成:获取一个数据源→数据转换→执行操作获取想要的结果。每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象,这就允许对其操作可以像链条一样排列,形成了一个管道。流(Stream)提供的功能非常有用,主要包括匹配、过滤、汇总、转化、分组、分组汇总等功能。
2.1.匹配集合数据
普通:
boolean isFound = false;
for (UserDO user : userList) {
if (Objects.equals(user.getId(), userId)) {
isFound = true;
break;
}
}
精简:
boolean isFound = userList.stream()
.anyMatch(user -> Objects.equals(user.getId(), userId));
2.2.过滤集合数据
普通:
List<UserDO> resultList = new ArrayList<>();
for (UserDO user : userList) {
if (Boolean.TRUE.equals(user.getIsSuper())) {
resultList.add(user);
}
}
精简:
List<UserDO> resultList = userList.stream()
.filter(user -> Boolean.TRUE.equals(user.getIsSuper()))
.collect(Collectors.toList());
2.3.汇总集合数据
普通:
double total = 0.0D;
for (Account account : accountList) {
total += account.getBalance();
}
精简:
double total = accountList.stream().mapToDouble(Account::getBalance).sum();
2.4.转化集合数据
普通:
List<UserVO> userVOList = new ArrayList<>();
for (UserDO userDO : userDOList) {
userVOList.add(transUser(userDO));
}
精简:
List<UserVO> userVOList = userDOList.stream()
.map(this::transUser).collect(Collectors.toList());
2.5.分组集合数据
普通:
Map<Long, List<UserDO>> roleUserMap = new HashMap<>();
for (UserDO userDO : userDOList) {
roleUserMap.computeIfAbsent(userDO.getRoleId(), key -> new ArrayList<>())
.add(userDO);
}
精简:
Map<Long, List<UserDO>> roleUserMap = userDOList.stream()
.collect(Collectors.groupingBy(UserDO::getRoleId));
2.6.分组汇总集合
普通:
Map<Long, Double> roleTotalMap = new HashMap<>();
for (Account account : accountList) {
Long roleId = account.getRoleId();
Double total = Optional.ofNullable(roleTotalMap.get(roleId)).orElse(0.0D);
roleTotalMap.put(roleId, total + account.getBalance());
}
精简:
roleTotalMap = accountList.stream().collect(Collectors.groupingBy(Account::getRoleId, Collectors.summingDouble(Account::getBalance)));
2.7.生成范围集合
Python 的 range 非常方便,Stream 也提供了类似的方法。
普通:
int[] array1 = new int;
for (int i = 0; i < N; i++) {
array1[i] = i + 1;
}
int[] array2 = new int;
array2[0] = 1;
for (int i = 1; i < N; i++) {
array2[i] = array2[i - 1] * 2;
}
精简:
int[] array1 = IntStream.rangeClosed(1, N).toArray();
int[] array2 = IntStream.iterate(1, n -> n * 2).limit(N).toArray();
3.利用程序结构
3.1.返回条件表达式
条件表达式判断返回布尔值,条件表达式本身就是结果。
普通:
public boolean isSuper(Long userId)
UserDO user = userDAO.get(userId);
if (Objects.nonNull(user) && Boolean.TRUE.equals(user.getIsSuper())) {
return true;
}
return false;
}
精简:
public boolean isSuper(Long userId)
UserDO user = userDAO.get(userId);
return Objects.nonNull(user) && Boolean.TRUE.equals(user.getIsSuper());
}
3.2.最小化条件作用域
普通:
Result result = summaryService.reportWorkDaily(workDaily);
if (result.isSuccess()) {
String message = \"上报工作日报成功\";
dingtalkService.sendMessage(user.getPhone(), message);
} else {
String message = \"上报工作日报失败:\" + result.getMessage();
log.warn(message);
dingtalkService.sendMessage(user.getPhone(), message);
}
精简:
String message;
Result result = summaryService.reportWorkDaily(workDaily);
if (result.isSuccess()) {
message = \"上报工作日报成功\";
} else {
message = \"上报工作日报失败:\" + result.getMessage();
log.warn(message);
}
dingtalkService.sendMessage(user.getPhone(), message);
3.3.调整表达式位置
调整表达式位置,在逻辑不变的前提下,让代码变得更简洁。
普通:
String line = readLine();
while (Objects.nonNull(line)) {
... // 处理逻辑代码
line = readLine();
}
精简:
for (String line = readLine(); Objects.nonNull(line); line = readLine()) {
... // 处理逻辑代码
}
3.4.利用非空对象
普通:
private static final int MAX_VALUE = 1000;
boolean isMax = (value != null && value.equals(MAX_VALUE));
boolean isTrue = (result != null && result.equals(Boolean.TRUE));
精简:
private static final Integer MAX_VALUE = 1000;
boolean isMax = MAX_VALUE.equals(value);
boolean isTrue = Boolean.TRUE.equals(result);
4.利用设计模式
模板方法模式(Template Method Pattern)定义一个固定的算法框架,而将算法的一些步骤放到子类中实现,使得子类可以在不改变算法框架的情况下重定义该算法的某些步骤。
4.1.模板方法模式
普通:
@Repository
public class UserValue {
/** 值操作 */
@Resource(name = \"stringRedisTemplate\")
private ValueOperations<String, String> valueOperations;
/** 值模式 */
private static final String KEY_FORMAT = \"Value:User:%s\";
/** 设置值 */
public void set(Long id, UserDO value) {
String key = String.format(KEY_FORMAT, id);
valueOperations.set(key, JSON.toJSONString(value));
}
/** 获取值 */
public UserDO get(Long id) {
String key = String.format(KEY_FORMAT, id);
String value = valueOperations.get(key);
return JSON.parseObject(value, UserDO.class);
}
...
}
@Repository
public class RoleValue {
/** 值操作 */
@Resource(name = \"stringRedisTemplate\")
private ValueOperations<String, String> valueOperations;
/** 值模式 */
private static final String KEY_FORMAT = \"Value:Role:%s\";
/** 设置值 */
public void set(Long id, RoleDO value) {
String key = String.format(KEY_FORMAT, id);
valueOperations.set(key, JSON.toJSONString(value));
}
/** 获取值 */
public RoleDO get(Long id) {
String key = String.format(KEY_FORMAT, id);
String value = valueOperations.get(key);
return JSON.parseObject(value, RoleDO.class);
}
...
}
精简:
public abstract class AbstractDynamicValue<I, V> {
/** 值操作 */
@Resource(name = \"stringRedisTemplate\")
private ValueOperations<String, String> valueOperations;
/** 设置值 */
public void set(I id, V value) {
valueOperations.set(getKey(id), JSON.toJSONString(value));
}
/** 获取值 */
public V get(I id) {
return JSON.parseObject(valueOperations.get(getKey(id)), getValueClass());
}
...
/** 获取主键 */
protected abstract String getKey(I id);
/** 获取值类 */
protected abstract Class<V> getValueClass();
}
@Repository
public class UserValue extends AbstractValue<Long, UserDO> {
/** 获取主键 */
@Override
protected String getKey(Long id) {
return String.format(\"Value:User:%s\", id);
}
/** 获取值类 */
@Override
protected Class<UserDO> getValueClass() {
return UserDO.class;
}
}
@Repository
public class RoleValue extends AbstractValue<Long, RoleDO> {
/** 获取主键 */
@Override
protected String getKey(Long id) {
return String.format(\"Value:Role:%s\", id);
}
/** 获取值类 */
@Override
protected Class<RoleDO> getValueClass() {
return RoleDO.class;
}
}