在 Java 8 裏,引入了一個 Optional 類,該類是一個能夠爲 null 的容器對象。算法
1.1.保證值存在設計模式
構造方法,能夠簡化對象的初始化和設置屬性操做。對於屬性字段較少的類,能夠自定義構造方法。app
普通:框架
Integer thisValue;
if (Objects.nonNull(value)) {
thisValue = value;
} else {
thisValue = DEFAULT_VALUE;
}
精簡:ide
Integer thisValue = Optional.ofNullable(value).orElse(DEFAULT_VALUE);
普通:this
Integer thisValue;
if (Objects.nonNull(value) && value.compareTo(MAX_VALUE) <= 0) {
thisValue = value;
} else {
thisValue = MAX_VALUE;
}
精簡:spa
Integer thisValue = Optional.ofNullable(value)
.filter(tempValue -> tempValue.compareTo(MAX_VALUE) <= 0).orElse(MAX_VALUE);
1.3 保證值合法
設計
普通:code
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();
}
}
}
精簡:
orm
tring zipcode = Optional.ofNullable(user).map(User::getAddress)
.map(Address::getCountry).map(Country::getZipcode).orElse(null);
流(Stream)是Java 8的新成員,容許你以聲明式處理數據集合,能夠當作爲一個遍歷數據集的高級迭代器。流主要有三部分構成:獲取一個數據源→數據轉換→執行操做獲取想要的結果。每次轉換原有 Stream 對象不改變,返回一個新的 Stream 對象,這就容許對其操做能夠像鏈條同樣排列,造成了一個管道。流(Stream)提供的功能很是有用,主要包括匹配、過濾、彙總、轉化、分組、分組彙總等功能。
普通:
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());
普通:
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[N];
for (int i = 0; i < N; i++) {
array1[i] = i + 1;
}
int[] array2 = new int[N];
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();
條件表達式判斷返回布爾值,條件表達式自己就是結果。
普通:
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()) {
... // 處理邏輯代碼
}
普通:
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);
模板方法模式(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; }}