1. 程式人生 > 實用技巧 >Java8-BiConsumer函式式介面

Java8-BiConsumer函式式介面

目錄

文章參考: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物件呼叫方法accept接受引數 sqlSession和user物件
            // 然後執行sqlSession.insert(sqlStatement,user)方法
            consumer.accept(sqlSession, element);
            
            if ((i % batchSize == 0) || i == size) {
                // 重新整理批處理語句:最終執行insert插入語句
                sqlSession.flushStatements();
            }
            i++;
        }
    });
}