java8新特性---函数参数化(::)

将函数作为参数化,并进行传递

1、定义函数接口

@FunctionalInterface
public interface ConvertPredict<T,V> {
    /**
     * 转换函数
     * @param t
     * @param v
     */
    void convert(T t,V v);
}

2、定义一系列函数

  函数的签名必须要跟函数接口的签名相同,返回值类型相同,参数个数相同

public class ConvertData {

    /**
     * 汽车合格证识别提取模板
     * 
     * @param tableCell
     * @param formResponse
     */
    public static void vechileConvertSh(TableCell tableCell, VechileBody vechileBody) {
        
          // 函数体,要实现的方法
    }

    public static void vechileConvertBj(TableCell tableCell, VechileBody vechileBody) {
        
          // 函数体,要实现的方法
    }

}

3、函数调用

  1、 ConvertPredict<TableCell, VechileBody> predicate 为函数类型的 参数

  2、<TableCell, VechileBody>表示函数入参的类型

  3、predicate.convert(tableCell, vechileBody);表示调用相应的函数

  4、ConvertData::vechileConvertSh表示将该函数作为参数传递

    @Override
    public FormResponse formRecogtest(ChannelRequest channelRequest,
            String recogType) {

        // 省略。。。

        // 将原始数据处理成需要返回的数据
        if (recogType != null && recogType.equals(ChannelConst.VECH_SH)) {// 如果是xxxx汽车证
            return delResult(channelResponse, ConvertData::vechileConvertSh);
        } else {// 没有指定合格证的类型
            return null;
        }

    }

    /**
     * 转换识别结果
     * 
     * @param channelResponse
     * @return
     */
    private FormResponse delResult(ChannelResponse<TableData> channelResponse,
            ConvertPredict<TableCell, VechileBody> predicate) {

        // 省略。。。
        formResponse.setVechileBodys(vechileBodies);
        // 循环多张图片数据
        for (OcrData<TableData> ocrData : channelResBody.getOcrDatas()) {
            // 一张图片中可能有多张表格
            List<TableData> lisTableDatas = ocrData.getData();
            for (TableData tableData : lisTableDatas) {

                    // 省略。。。
                    for (TableCell tableCell : tableBody.getCellList()) {
                        // 将单元格对应到相应的返回数据中
                        predicate.convert(tableCell, vechileBody);
                    }
                }
                vechileBodies.add(vechileBody);
            }
        }
        return formResponse;

    }

以下为转载

JDK8中有双冒号的用法,就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下。

以前的代码一般是如此的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public class AcceptMethod {

    public static void  printValur(String str){

        System.out.println("print value : "+str);

    }

    public static void main(String[] args) {

        List<String> al = Arrays.asList("a","b","c","d");

        for (String a: al) {

            AcceptMethod.printValur(a);

        }

          //下面的for each循环和上面的循环是等价的 

        al.forEach(x->{

            AcceptMethod.printValur(x);

        });

    }

}

  现在JDK双冒号是:

1

2

3

4

5

6

7

8

9

10

11

12

13

public class AcceptMethod {

    public static void  printValur(String str){

        System.out.println("print value : "+str);

    }

    public static void main(String[] args) {

        List<String> al = Arrays.asList("a""b""c""d");

        al.forEach(AcceptMethod::printValur);

        //下面的方法和上面等价的

        Consumer<String> methodParam = AcceptMethod::printValur; //方法参数

        al.forEach(x -> methodParam.accept(x));//方法执行accept

    }

}

   上面的所有方法执行玩的结果都是如下:

1

2

3

4

print value : a

print value : b

print value : c

print value : d

  在JDK8中,接口Iterable 中默认实现了forEach方法,调用了 JDK8中增加的接口Consumer内的accept方法,执行传入的方法参数。

JDK源码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/**

     * Performs the given action for each element of the {@code Iterable}

     * until all elements have been processed or the action throws an

     * exception.  Unless otherwise specified by the implementing class,

     * actions are performed in the order of iteration (if an iteration order

     * is specified).  Exceptions thrown by the action are relayed to the

     * caller.

     *

     * @implSpec

     * <p>The default implementation behaves as if:

     * <pre>{@code

     *     for (T t : this)

     *         action.accept(t);

     * }</pre>

     *

     * @param action The action to be performed for each element

     * @throws NullPointerException if the specified action is null

     * @since 1.8

     */

    default void forEach(Consumer<? super T> action) {

        Objects.requireNonNull(action);

        for (T t : this) {

            action.accept(t);

        }

    }

 另外补充一下,JDK8改动的,在接口里面可以有默认实现,就是在接口前加上default,实现这个接口的函数对于默认实现的方法可以不用再实现了。类似的还有static方法。现在这种接口除了上面提到的,还有BiConsumer,BiFunction,BinaryOperation等,在java.util.function包下的接口,大多数都有,后缀为Supplier的接口没有和别的少数接口。

猜你喜欢

转载自blog.csdn.net/yangchuanan/article/details/82351323
今日推荐