【再学一次系列】Lambda内置函数式接口

404 阅读3分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战

前言

哈喽大家好,我是卡诺,一名致力于成为全栈的全粘工程师!

通过上一章「Lambda必知必会」我们自定义了函数式接口以及使用,相信大家对Lambda有了一定的认识。事实上在实际项目开发中我们很少会自定义函数式接口,因为Java本身为我们内置的函数接口基本上够我们日常开发使用。本章我们要学习Java内置的、常用的函数式接口。

内置函数式接口及使用

函数式接口源码详见java.util.function包

Supplier

生产接口:不接受参数,返回一个<T>类型的值!适合创建对象,演示如下:

public void testSupplier(){
    Supplier<Fruit> supplier = () -> new Banana();
    System.out.println(supplier.get());//com.uucoding.java.entity.Banana@11438d26
}

Consumer

消费接口:接受一个<T>类型参数,无返回值!适合访问一个数据,并对其执行一些操作,演示如下:

public void testConsumer(){
    Consumer<String> consumer = val -> System.out.println(val);
    consumer.accept("Consumer hello word"); // "Consumer hello word"
}

Predicate

布尔接口:接受一个<T>类型参数,并返回true / false!适合对T类型数据操作后返回布尔值,演示如下:

public void testPredicate(){
    Predicate<String> predicate = (str) -> Objects.nonNull(str);
    System.out.println(predicate.test("100")); // true
}

Function

函数接口:接受一个<T>类型参数,并返回一个<R>类型的值!适合处理入参,并返回处理结果,演示如下:

public void testFunction(){
    Function<String, Integer> function = (str2Int) -> Integer.valueOf(str2Int);
    System.out.println(function.apply("100")); // 100
}

BiFunction

增强函数接口:接受<T><U>类型的两个参数,并返回一个<R>类型的值,演示如下:

public void testBiFunction(){
    BiFunction<Integer, Integer, String> biFunction = (a, b) -> String.valueOf(a + b);
    System.out.println(biFunction.apply(1, 2)); // "3"
}

以上五个函数接口是我在工作中经常使用的,你们呢?

内置接口中有的还包含一些默认方法的实现,大家有兴趣的可以看一看,这些默认方法本质上还是通过Lambda的形式对某些关联函数接口进行组合或做一些简化操作。

类型特化

我们知道Java存在装箱拆箱(由Java自动完成),即将基本类型(int、long等)转化为引用类型(Interger、Long等)称之装箱(本质就是将原始类型包装并保存在堆中,装箱后需要更多的内存)反之则为拆箱。如下代码:

public void testQuoteType(){
    Consumer<Long> consumer = (val) -> System.out.println(val);
    consumer.accept(10L); // 10
}

泛型接口的类型只能绑定引用类型,上述代码中long自动被装箱成Long,这个在性能方面是需要付出一定代价的。Java在java.util.function包中为我们提供针对原始类型的函数式接口,如:LongConsumerLongFunctionLongPredicateLongSupplier等,上述代码可以优化成如下形式:

public void testLongConsumer(){
    LongConsumer consumer = (val) -> System.out.println(val);
    consumer.accept(10L); // 10
}

基本类型使用种特化的接口可以避免装箱拆箱的操作,从而提高性能!

源码

总结

  • 本章主要针对Java内置的接口进行讲解及案例编写;
  • 为了避免装箱,当泛型是基本类型的时候请尽可能的使用内置的特化函数式接口;
  • 尽量直接使用Java内置的函数式接口,除非这些接口都不满足。

关联文章

👉【再学一次系列】

最后

  • 感谢铁子们耐心看到最后,如果大家感觉本文有所帮助,麻烦给个赞👍关注➕
  • 由于本人技术有限,文章和代码可能存在错误,希望大家评论指出,万分感激🙏;
  • 同时也欢迎大家V我一起讨论学习web前端、Java等IT知识,一起卷一起进步。