文章參考:https://blog.csdn.net/caoxiaohong1005/article/details/79486254
BiConsumer<T, U>函數式接口
函數式接口實踐
實踐一:Comsumer函數式接口
/**
* Consumer函數式接口測試
*/
@Test
public void testFunction01(){
// 創建字符串對象
StringBuilder sb = new StringBuilder("sb字符串后面將會跟隨####");
// 聲明函數對象 consumer
Consumer<StringBuilder> consumer = (str) -> str.append("大SB");
// 調用Consumer.accept()方法接收參數
consumer.accept(sb);
System.out.println(sb.toString());
}
運行結果:
sb字符串后面將會跟隨####大SB
實踐二:BiConsumer函數式接口
@Test
public void testFunction02(){
// 創建字符串對象
StringBuilder sb = new StringBuilder();
// 聲明函數對象 consumer
BiConsumer<String,String> consumer = (str1, str2) -> {
// 拼接字符串
sb.append(str1);
sb.append(str2);
};
// 調用Consumer.accept()方法接收參數
consumer.accept("我是參數01",",我是參數02。我們被BiConsumer.accept(T,V)接收並處理了");
System.out.println(sb);
}
運行結果:
我是參數01,我是參數02。我們被BiConsumer.accept(T,V)接收並處理了
函數式接口源碼
package sourcecode.analysis;
import java.util.Objects;
/**
* to operate via side-effects.
* 本函數接口特征:
* 1.輸入參數2個.
* 2.無輸出結果
* 3.本函數接口和Consumer函數接口唯一區別:
* 4.和其它函數接口不同的是:BiConsumer接口的操作是通過其副作用而完成的.
* 5.本函數接口功能方法:accept(t,u)
*
* @param <T> 第一個操作參數類型
* @param <U> 第二個操作參數類型
*
* @see java.util.function.Consumer
* @since 1.8
*/
@FunctionalInterface
public interface BiConsumer<T, U> {
/**
* 本方法的調用,會對輸入參數執行指定的行為
* @param t 第一個輸入參數
* @param u 第二個輸入參數
*/
void accept(T t, U u);
/**
* andThen方法,會執行兩次Consumer接口的accept方法.兩次執行順序上,先對輸入參數執行accept()方法;然后
* 再對輸入參數執行一次after.accept()方法.(注意:兩次均為對輸入參數的操作,after操作並不是對第一次accept結果的操作)
* 這兩次任何一次accept操作出現問題,都將拋異常到方法調用者處.
* 如果執行accept這一操作出現異常,fater操作將不會執行.
* @return 一個按順序執行的組合的{BiConsumer} 操作后面跟着{@code after}操作
*/
default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
Objects.requireNonNull(after);
return (l, r) -> {
accept(l, r);
after.accept(l, r);
};
}
}
MybatisPlus中的函數式接口的調用分析
/**
* 獲取 SqlStatement
*
* @param sqlMethod ignore
* @return ignore
*/
protected String sqlStatement(SqlMethod sqlMethod) {
return SqlHelper.table(entityClass).getSqlStatement(sqlMethod.getMethod());
}
@Override
public boolean saveBatch(Collection<User> entityList, int batchSize) {
// 獲取insert插入語句:INSERT INTO xxx VALUES xxx
String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
// 執行批量刪除操作
// 參數一:entity集合
// 參數二:執行次數
// 參數三 : 接收兩個參數的函數接口並執行 sqlSession.insert(sqlStatement,user)方法
return executeBatch(entityList, batchSize,
(sqlSession, user) -> sqlSession.insert(sqlStatement,user));
}
/**
* 執行批量操作
*
* @param list 數據集合
* @param batchSize 批量大小
* @param consumer 執行方法
* @param <E> 泛型
* @return 操作結果
* @since 3.3.1
*/
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
Assert.isFalse(batchSize < 1, "batchSize must not be less than one");
return !CollectionUtils.isEmpty(list) && executeBatch(sqlSession -> {
int size = list.size();
int i = 1;
for (E element : list) {
// comsumer 對象引用函數(sqlSession, user)
// 調用方法 accept 接收參數 SqlSession 和 User對象的引用
// 然后執行 sqlSession.insert(sqlStatement,user) 方法
consumer.accept(sqlSession, element);
if ((i % batchSize == 0) || i == size) {
// 刷新批處理語句:最終執行 insert 插入語句
sqlSession.flushStatements();
}
i++;
}
});
}