別人說爛了的stream api不就不想贅述了,我想和大家分享一下,如何用函數(shù)式編程來簡化我們的開發(fā),想說點不一樣的東西
轉(zhuǎn)載鏈接
簡化事務(wù)
對于事務(wù)而言,應(yīng)該粒度越小越好,并且讀寫邏輯應(yīng)該分開,只在寫的邏輯上執(zhí)行事務(wù),可以用函數(shù)式編程來簡化抽去寫邏輯這一步
@Service
public class TransactionService {
@Transactional
public void process(ThrowExceptionRunnable runnable){
try {
runnable.run();
}catch (Exception e){
new RuntimeException(e);
}
}
}
//使用方式
public void regist(String username){
User user = userService.findByUserName(username);
if(user != null) return;
//執(zhí)行事務(wù) 注冊用戶 開通余額賬號
transactionService.process(() -> {
userService.save(new User(username));
balanceService.save(new Balance(username));
});
}
賦予方法重試能力
public static void retryFunction(ThrowExceptionRunnable runnable, int time) {
while (true) {
try {
runnable.run();
return;
} catch (Exception e) {
time--;
if (time <= 0) throw new RuntimeException(e);
}
}
}
public static <T, R> R retryFunction(ThrowExceptionFunction<T, R> function, T t, int time) {
while (true) {
try {
return function.apply(t);
} catch (Exception e) {
time--;
if (time <= 0) throw new RuntimeException(e);
}
}
}
public static <T, U, R> R retryFunction(ThrowExceptionBiFunction<T, U, R> function, T t, U u, int time) {
while (true) {
try {
return function.apply(t, u);
} catch (Exception e) {
time--;
if (time <= 0) throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
//http調(diào)用,失敗會重試3次
retryFunction(()->http.call(),3);
//把數(shù)字1轉(zhuǎn)成數(shù)字 失敗會重試三次
String s = retryFunction(String::valueOf, 1, 3);
String ss = retryFunction(i -> String.valueOf(i), 1, 3);
}
賦予函數(shù)緩存能力
public static <T, R> R cacheFunction(Function<T, R> function, T t, Map<T, R> cache) {
R r = cache.get(t);
if (r != null) return r;
R result = function.apply(t);
cache.put(t,result);
return result;
}
public static void main(String[] args) {
Map<String,User> cache = new HashMap<Integer, User>();
String username = "張三";
//不走緩存
cacheFunction(u -> userService.findByUserName(u),username,cache);
//走緩存
cacheFunction(u -> userService.findByUserName(u),username,cache);
}
賦予函數(shù)報錯返回默認值能力
public static <T, R> R computeOrGetDefault(ThrowExceptionFunction<T, R> function, T t, R r) {
try {
return function.apply(t);
} catch (Exception e) {
return r;
}
}
public static <R> R computeOrGetDefault(ThrowExceptionSupplier<R> supplier,R r){
try {
return supplier.get();
} catch (Exception e) {
return r;
}
}
public static void main(String[] args) {
//返回0
computeOrGetDefault(i -> {
if (i < 0) throw new RuntimeException();
else return i;
}, -1, 0);
//返回5
computeOrGetDefault(i -> {
if (i < 0) throw new RuntimeException();
else return i;
},5,0);
}
賦予函數(shù)處理異常的能力
public static <T, R> R computeAndDealException(ThrowExceptionFunction<T, R> function, T t, Function<Exception, R> dealFunc) {
try {
return function.apply(t);
} catch (Exception e) {
return dealFunc.apply(e);
}
}
public static <T, U, R> R computeAndDealException(ThrowExceptionBiFunction<T,U, R> function, T t, U u,Function<Exception, R> dealFunc) {
try {
return function.apply(t,u);
} catch (Exception e) {
return dealFunc.apply(e);
}
}
public static <R> R computeAndDealException(ThrowExceptionSupplier<R> supplier, Function<Exception, R> dealFunc) {
try {
return supplier.get();
} catch (Exception e) {
return dealFunc.apply(e);
}
}
public static void main(String[] args) {
//返回異常message的hashcode
Integer integer = computeAndDealException(i -> {
if (i < 0) throw new RuntimeException("不能小于0");
else return i;
}, -1, e -> e.getMessage().hashCode());
System.out.println(integer);
}
賦予函數(shù)記錄日志能力
public static <T, R> R logFunction(Function<T, R> function, T t, String logTitle) {
long startTime = System.currentTimeMillis();
log.info("[[title={}]],request={},requestTime={}", logTitle, t.toString(),
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
R apply = function.apply(t);
long endTime = System.currentTimeMillis();
log.info("[[title={}]],response={},spendTime={}ms", logTitle, apply.toString(), endTime - startTime);
return apply;
}
public static void main(String[] args) {
logFunction(String::valueOf,"s","String.valueOf");
}
自定義函數(shù)接口
@FunctionalInterface
public interface ThrowExceptionFunction<T, R> {
R apply(T t) throws Exception;
}
@FunctionalInterface
public interface ThrowExceptionBiFunction<T, U, R> {
R apply(T t, U u) throws Exception;
}
@FunctionalInterface
public interface ThrowExceptionSupplier<T> {
T get() throws Exception;
}
@FunctionalInterface
public interface ThrowExceptionRunnable {
void run() throws Exception;
}
Q:為什么要自定義函數(shù)接口
A:自帶的函數(shù)接口無法處理檢查異常,遇見帶檢查異常的方法會報錯
我哪些場景用到了?
鏈?zhǔn)饺?shù)
在翻譯php代碼的時候我們常常遇到如下情況
$s = a.b.c.d.e.f.g
然后翻譯成java代碼的時候是這樣的
String s = a.getB().getC().getD().getE().getF().getG();
有啥問題?沒有沒有判空,只要中間有一層為空,那么就是NPE,要是去寫判空邏輯的話,真是要了命了
這時我們就可以用上上面提到的騷操作了文章來源:http://www.zghlxwxcb.cn/news/detail-796240.html
代碼改寫文章來源地址http://www.zghlxwxcb.cn/news/detail-796240.html
String s = computeOrGetDefault(()->a.getB().getC().getD().getE().getF().getG(),"");
事務(wù)
簡單的降級操作(computeAndDealException)
接口重試
接口緩存
記錄日志
到了這里,關(guān)于Java函數(shù)式編程最佳實踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!