Java8中四种基础函数式接口

目录

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);

            }

        }
public static void testConsumer1() {
    Consumer<String> consumer = s ->  LOGGER.info(s.concat(" 是一名拆书家"));
    consumer.accept("天天");
  }

 

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可以作为一个参数进行传递。

 

 

 

 

 

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值