欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java8中四种基础函数式接口

程序员文章站 2022-03-26 17:10:08
Java8中四种基础函数式接口函数式接口参数类型返回类型用途举例Function{R apply(T t);}T,RR给定指定类型T的参数,返回R类型的结果,将函数限定。对内容进行处理。比如给一张白纸,返回一张好看的画P......

目录

Java8中四种基础函数式接口

1,函数式接口 Function:apply

接口: Function,>

基础:

apply的使用

2,断言式接口 Predicate:test

基础:

使用

3,消费式接口 Consumer:accept

4,供给式接口 Supplier: get

总结


 

Java8中四种基础函数式接口

 

函数式接口

参数类型

返回类型

用途

举例

Function<T, R>{R apply(T t);} 

TR

R

给定指定类型T的参数,返回R类型的结果,将函数限定。

对内容进行处理。比如给一张白纸,返回一张好看的画

Predicate{boolean test(T t);} 
 

T

boolean

给定指定类型T的参数,计算出断言式的boolean型结果

对内容进行过滤。比如公司招人,选适合的人

Consumer{void accept(T t);} 
 

T

void

给定类型为T的参数,执行操作

对内容进行输出。比如在超市买东西,打印的小票,这样就可以看到明细了

Supplier{T get();} 
 

void

T

获得给定类型T的结果,不传参数

 提供相似的内容。比如:用的铅笔没了,提供其他铅笔用

 

 

 

  Lambda表达式是函数式接口的基础,可以将 lambda 表达式视为一个对象,将其作为参数传递

 

 

1,函数式接口 Function:apply

 

接口: Function<T, R>


 

public interface Function<T, R> {

 

    R apply(T t);

  

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {

        Objects.requireNonNull(before);

        return (V v) -> apply(before.apply(v));

    }

   

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {

        Objects.requireNonNull(after);

        return (T t) -> after.apply(apply(t));

    }

  

    static <T> Function<T, T> identity() {

        return t -> t;

    }

}

 

apply: 应用,这个方法是最常见的

 

compose: 构成之前,在apply之前,先进行XX操作

 

andThen:构成之后,在apply之后,进行YY操作

 

 

identity: 唯一,在Collectors.toMap中使用,保证key对应的值的唯一性;

 

 

 

基础:


 

/**
 * Function是一个函数式接口,其中有四个方法 apply, compose, andThen, testIndetify()
 *   // 先执行输入的Function,其结果作为参数再作为调用者的Function的参数
 *     default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
 *         Objects.requireNonNull(before);
 *         return (V v) -> apply(before.apply(v));
 *     }
 *
 * // 先执行调用者的Function,其结果作为参数再作为输入的Function的参数
 *     default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
 *         Objects.requireNonNull(after);
 *         return (T t) -> after.apply(apply(t));
 *     }
 *
 */


public static void main(String[] args) {

    Function<String, String> applyFunc = s -> s.concat(" function ");
    Function<String, String> composeFunc = s -> s.concat(" compose ");
    Function<String, String> andThenFunc = s -> s.concat(" andThen ");
    System.out.println(applyFunc.apply("yan"));
    System.out.println(applyFunc.compose(composeFunc).apply(" yan "));
    System.out.println(applyFunc.andThen(andThenFunc).apply(" yan "));


    testComposeAndThen();
}

public static void testComposeAndThen(){
    int res1 = compute1(1, e -> e + 1); // 结果:2
    int res2 = compute2(2, e -> e + 3, e -> e * 3); // 结果:9
    int res21 = compute21(2, e -> e + 3, e -> e * 3); // 结果:15
    int res3 = compute3(3, e -> e + 4, e -> e * 3); // 结果:13
    int res31 = compute4(3, e -> e + 4, e -> e * 3); // 结果:14
    System.out.println(res1 + ", " + res2 + ", " + res21 + ", " + res3 + ", " + res31);
}



public static int compute1(int x, Function<Integer, Integer> function) {
    return function.apply(x);
}

public static int compute2(int x, Function<Integer, Integer> after, Function<Integer, Integer> before) {
    // x作为before的参数,其结果再作为after的参数
    return after.compose(before).apply(x);
}

public static int compute21(int x, Function<Integer, Integer> after, Function<Integer, Integer> before) {
    // x作为before的参数,其结果再作为after的参数
    return before.compose(after).apply(x);
}

public static int compute3(int x, Function<Integer, Integer> after, Function<Integer, Integer> before) {
    // x作为after的参数先执行after的计算,其结果再作为before的参数
    return before.andThen(after).apply(x);
}

public static int compute4(int x, Function<Integer, Integer> after, Function<Integer, Integer> before) {
    // x作为after的参数先执行after的计算,其结果再作为before的参数
    return after.andThen(before).apply(x);
}


public static void testIndetify(){
    List<Map<String, Object>> neIdList = new ArrayList<>();
    Map<String, Object> paas = new HashMap<>(8);
    paas.put("FILE_FIELD", "times");
    paas.put("AGG_TYPE", "sum");
    neIdList.add(paas);
    Map<String, Object> paas2 = new HashMap<>(8);
    paas2.put("FILE_FIELD", "times");
    paas2.put("AGG_TYPE", "sum2");
    neIdList.add(paas2);

    Map<String, Map<String, Object>> identifyMap =
            ListUtils.emptyIfNull(neIdList).stream()
                    .collect(Collectors.toMap(e -> MapUtils.getString(e, "FILE_FIELD"), Function.identity(), (x, y) -> x));
    System.out.println(identifyMap.toString());
}

 

 

apply的使用

 

public static void main(String[] args) {



    List<String> strList = Arrays.asList("orderType", "virtualOrderId", "cityCode");

    List<Integer> strSizeList = map(strList, String::length);

    strSizeList.forEach(System.out::println);

    List<Integer> numAddList = map(strSizeList, (Integer s) -> s + 100);

    numAddList.forEach(System.out::println);

    List<String> concatOne = map(strList, (String s) -> s.concat(" one"));

    concatOne.forEach(System.out::println);



}




public static <T, R> List<R> map(List<T> list, Function<T, R> func) {

    return ListUtils.emptyIfNull(list).stream().map(func).collect(Collectors.toList());

}
 

2,断言式接口 Predicate:test

 

Predicate:断言,使基于,我倾向于后者的理解,基于什么去判断

 

基础:

//    Stream<T> filter(Predicate<? super T> predicate);

    public static <T> List<T> filter(List<T> list, Predicate<T> p) {

        List<T> results = new ArrayList<>();

        for (T s : list) {

            if (p.test(s)) { // 判断是否符合条件

                results.add(s);

            }

        }

        return results;

    }





    public static void main(String[] args) {

        testEmpty();

        testFilterSize();

        testFilterValue();

    }



    public static void testEmpty() {

        Predicate<String> nonEmptyStrPre = (String s) -> !s.isEmpty();

        List<String> aa = Arrays.asList("Hello", "", "Predict", "123", "ok");

        List<String> nonEmpty = filter(aa, nonEmptyStrPre);

        nonEmpty.forEach(System.out::println);



        List<String> nonEmpty2 = filter(aa, s -> s.length() > 2);

        nonEmpty2.forEach(System.out::println);

    }



    public static void testFilterSize() {

        List<String> list = Arrays.asList("Hello", "Java8", "Lambda", "www", "ok");

        ListUtils.emptyIfNull(list).stream().filter(s -> s.length() > 3).collect(Collectors.toList());

        List<String> strList = filter(list, (s) -> s.length() > 3);

        strList.forEach(System.out::println);

    }



    public static void testFilterValue() {

        List<Integer> list = Arrays.asList(88, 44, 99, 980, 121212);

        List<Integer> strList = filter(list, (s) -> s > 300);

        strList.forEach(System.out::println);

    }

 

 

 

 

使用

 

// 在接口:Collection<E>

default boolean removeIf(Predicate<? super E> filter) {

        Objects.requireNonNull(filter);

        boolean removed = false;

        final Iterator<E> each = iterator();

        while (each.hasNext()) {

            if (filter.test(each.next())) {

                each.remove();

                removed = true;

            }

        }

        return removed;

}

 

3,消费式接口 Consumer:accept

Consumer 消费:主要是输出内容

public static void main(String[] args) {

    forEach(Arrays.asList(1, 2, 3, 4, 5), (Integer i) -> System.out.println(i));

    forEach(Arrays.asList("yan", "I", "wonder"), (String i) -> System.out.println(i));

}

public static <T> void forEach(List<T> list, Consumer<T> c) {

    for (T s : list) {

        c.accept(s);

    }

}
// 在接口:Iterable<T> 中

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

            Objects.requireNonNull(action);

            for (T t : this) {

                action.accept(t);

            }

        }

 

 

4,供给式接口 Supplier: get

Supplier  提供同类型的数据内容,可以是单个或是多个,

 

public static void main(String[] args) {



    Random random = new Random();

    List<Integer> list = supplierSum(10, () -> random.nextInt(10));

    list.forEach(System.out::println);



}



public static List<Integer> supplierSum(int total, Supplier<Integer> sup) {

    List<Integer> list = new ArrayList<>();

    for (int i = 0; i < total; i++) {

        list.add(sup.get());

    }

    return list;

}

 

总结

       四个基础函数式编程接口中,Function 和 Predicate 会用得比较多,在steam中的 方法map (<R> Stream<R> map(Function<? super T, ? extends R> mapper); ) 和 filter方法 (Stream<T> filter(Predicate<? super T> predicate)),用到的频率就很高。

      在函数编程的理解中,主要是理解基础lambda可以作为一个参数进行传递。

 

 

 

 

 

本文地址:https://blog.csdn.net/qq_35461948/article/details/110234767