0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

JDK中常见的Lamada表达式

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-10-10 15:07 次阅读

JDK中有许多函数式接口,也会有许多方法会使用函数式接口作为参数,同时在各种源码中也大量使用了这些方法,那么我们在实际工作中应该如何使用!我们就来盘一盘,这样也有助于写出优雅的代码,使我们在阅读源码时事半功倍。

1 JDK中常见的Lamada表达式

Java中可以使用Lamada表达式的接口都有@FunctionalInterface注解。

先来看看util.function包下面含有FunctionalInterface注解的接口。一屏显示不全,可见功能非常齐全。

鉴于常用的一些函数式接口有Function/Consumer/Supplier/Predicate以及Runnable等。本篇介绍这几类接口。

图片

图片

1.1 Runnable

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Runnable 使用Lamada方式书写时,无参数,无返回值。最终执行的是run方法

使用Demo

new Thread(() - > {
    System.out.println("JavaNorth Runnable");
}).start();

1.2 Function

Function 表示接受一个参数并产生结果的函数。

@FunctionalInterface
public interface Function< T, R > {
    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    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;
    }
}

Function接受一个参数T,并且有返回值 R, 其实现也主要是实现此方法 R apply(T t);

Function 的一个示例:

List< String > list = new ArrayList< String >();
List< String > collect = list.stream().map((x) - > {
    return "Java North Function" + x;
}).collect(Collectors.toList());

上述示例中是一个stream的map方法。其中x为输入参数,『"Java North and" + x』为输出。

1.3 Consumer

Consumer表示接受一个参数,没有返回值的操作,主要方法为 void accept(T t);

@FunctionalInterface
public interface Consumer< T > {
    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    default Consumer< T > andThen(Consumer< ? super T > after) {
        Objects.requireNonNull(after);
        return (T t) - > { accept(t); after.accept(t); };
    }
}
1.3.1 Consumer 在Java中的应用

常见的有List的forEach等。

list.forEach(x - > System.out.println( "Java North Consumer test " + x));

x为参数,输出语句直接执行。

下面的map的forEach参数为BiConsumer,其入参有两个。

Map String,String > map = new HashMap  >();
map.forEach((K,V) - > {
    System.out.println("Java North Big Consumer MAP key : " +K + " value: "+V );
});
1.3.2 自定义带有Consumer的方法
public class ConsumerBiConsumerDemo {
    public static void main(String[] args) {
        Consumer< String > conString = (x) - > System.out.println(x.toUpperCase());
        conString.accept("i love java north ");

        BiConsumer< String, String > biCon = (x,y) - > System.out.println (x + y);
        biCon.accept("i love ","java");

        List< Person > plist = Arrays.asList(new Person("Java"),new Person("North"));
        acceptAllEmployee(plist,p - > System.out.println(p.name));
        acceptAllEmployee(plist,person - > {person.name = "unknow";});
        acceptAllEmployee(plist,person - > System.out.println(person.name));
    }

    public static void acceptAllEmployee(List< Person > plist, Consumer< Person > con){
        plist.forEach(person - > {con.accept(person);});
    }
}
class Person{
    public String name;
    public Person (String name){
        this.name = name;
    }
}

1.4 Supplier

Supplier没有参数,有一个返回值。

@FunctionalInterface
public interface Supplier< T > {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

Supplier 示例如下:

public class SupplierDemo {

    public static void main(String[] args) {
        SupplierDemo sdemo = new SupplierDemo();
        Supplier< LocalDateTime > s = () - > LocalDateTime.now();
        LocalDateTime localDateTime = s.get();
        System.out.println(s.get());

        Supplier< List > listSupplier = sdemo.listSupplier();
        List list = listSupplier.get();

        Person person = personFactory(Person::new);
        System.out.println(person);

        Person javaNorth = personFactory(() - > new Person("JavaNorth"));
        System.out.println(javaNorth);
    }

    public Supplier< List > listSupplier(){
        return ArrayList::new;
    }


    public static Person personFactory(Supplier< ? extends Person > s){
        Person person = s.get();
        if(person.getName() == null)  person.setName("default");
        person.setAge(18);
        return person;
    }


    static class Person {
        String name;
        int age;
        public Person() {   }
        public Person(String name) {
            this.name = name;
        }
       。。。
    }
}

1.5 Predicate

主要方法为test,其主要是传入一个参数,返回一个boolean类型的值。

@FunctionalInterface
public interface Predicate< T > {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

    default Predicate< T > and(Predicate< ? super T > other) {
        Objects.requireNonNull(other);
        return (t) - > test(t) && other.test(t);
    }

    default Predicate< T > negate() {
        return (t) - > !test(t);
    }

    default Predicate< T > or(Predicate< ? super T > other) {
        Objects.requireNonNull(other);
        return (t) - > test(t) || other.test(t);
    }
 ......
}

Predicate简单示例:

public class PredicateDemo {
    public static void main(String[] args) {
        Predicate< Integer > predicate = (s) - > s > 5;
        Predicate< Integer > predicate2 = (s) - > s > 8;
        System.out.println(" 3 大于5 ? " + predicate.test(3));
        System.out.println(" 6 大于5 ? " + predicate.test(6));

        System.out.println("7 大于5 and 大于8 " + predicate.and(predicate2).test(7));
        System.out.println("7 大于5 or 大于8 " + predicate.or(predicate2).test(7));

        List< Integer > list = Arrays.asList(3,5,6,2,8,4,7,9);
        List< Integer > collect = list.stream().filter(predicate).collect(Collectors.toList());

        System.out.println(list);
        System.out.println(collect);
    }
}

上述代码运行结果

3 大于5 ? false
 6 大于5 ? true
7 大于5 and 大于8 false
7 大于5 or 大于8 true
[3, 5, 6, 2, 8, 4, 7, 9]
[6, 8, 7, 9]

2 常用的Lamada参数特征

Lamada 的一些表达式将方法的一些执行逻辑放到了参数中,使得方法的返回值根据传入的参数的逻辑而变化。从而实现了在一定的方法不变的情况下,使代码执行传入参数相关的逻辑。

常用的一些Lamada使用如下:

Runnable 无入参,无返回值

() - > { System.out.println(strF.apply("javaNorth Runnable"));}

Function 有入参,有返回值

Function strF = (s) - > { return s + "javaNorth Function"; };
System.out.println(strF.apply("TEST "));

Consumer有入参,无返回值。

Consumer< String > srtC = (s) - > {System.out.println(s + "javaNorth TEST ");};
srtC.accept("Hello World");

Supplier 无入参,有返回值。

Supplier< String > srtP = () - > {return "I love avaNorth ";};
System.out.println(srtP.get());

Predicate 有入参,返回一个boolean类型的值

Predicate< Integer > predicate = (s) - > s > 5;
System.out.println(" 3 大于5 ? " + predicate.test(3));

3 自定义Lamada函数式接口

结合之前的常用Lamada函数的介绍,下面我们自定义一个简单的函数式接口。

@FunctionalInterface
public interface MyFunction< T > {
   public void print(T t);
}

public class MyFunctionDemo {
    public static void printString(String str , MyFunction< String > myF){
        myF.print(str);
    }
    public static void main(String[] args) {
        printString("I love " , (str) - > {System.out.println(str + "Java North");});
    }
}

其实很简单,就是展示了一下自定义函数式接口的应用实例而已。

总结

函数式接口的使用可以简化我们的代码,很大程度上提高代码的可读性。在程序执行上可能性能稍微有所降低,但对开发带来的便捷与好处是大于其性能上的微弱损失的。除了介绍的几种常见的函数式编程以外,还有许多其他的函数式接口等着我们去利用。听完这些话之后,软软猿妹也对常用的函数式接口有所了解,接下来下定决心要好好学一学函数式接口了。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    7640

    浏览量

    148509
  • 函数
    +关注

    关注

    3

    文章

    3882

    浏览量

    61310
  • JDK
    JDK
    +关注

    关注

    0

    文章

    77

    浏览量

    16489
收藏 人收藏

    评论

    相关推荐

    什么是正则表达式?正则表达式如何工作?哪些语法规则适用正则表达式

    正则表达式又称规则表达式(Regular Expression,在代码中常简写为 regex、regexp 或 RE),是一种用于匹配、查找、替换文本的强大工具。它能够以特定的模式匹配字符串,从而
    的头像 发表于 11-03 14:41 568次阅读
    什么是正则<b class='flag-5'>表达式</b>?正则<b class='flag-5'>表达式</b>如何工作?哪些语法规则适用正则<b class='flag-5'>表达式</b>?

    如何创建正则的表达式

    正则表达式:用于匹配规律规则的表达式,正则表达式最初是科学家对人类神经系统的工作原理的早期研究,现在在编程语言中有广泛的应用,经常用于表单校验,高级搜索等。
    发表于 10-27 15:49

    防范表达式的失控

    在C 语言中,表达式是最重要的组成部分之一,几乎所有的代码都由表达式构成。表达式的使用如此广泛,读者也许会产生这样的疑问,像+ 、- 、3 、/ 、& & 这样简单的运算也会出现
    发表于 04-22 16:57 13次下载

    Python正则表达式指南

    本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例。本文的内容不包括如何编写高效的正则表达式、如何优化正则
    发表于 03-26 09:13 10次下载
    Python正则<b class='flag-5'>表达式</b>指南

    Oracle中常用的函数与表达式讲解

    Oracle中常用的函数与表达式讲解(ups电源技术支持工程师招聘)-该文档为Oracle中常用的函数与表达式讲解文档,是一份还算不错的参考文档,感兴趣的可以看看,,,,,,,,,,,
    发表于 09-28 12:56 2次下载
    Oracle<b class='flag-5'>中常</b>用的函数与<b class='flag-5'>表达式</b>讲解

    Lambda表达式详解

    C++11中的Lambda表达式用于 **定义并创建匿名的函数对象** ,以简化编程工作。下面看一下Lambda表达式的基本构成。
    的头像 发表于 02-09 11:28 849次阅读

    表达式与逻辑门之间的关系

    逻辑表达式是指表示一个表示逻辑运算关系的式子,是一个抽象的类似数学表达式,下面我们重点说明下其表达式与逻辑门之间的关系。
    的头像 发表于 02-15 14:54 1116次阅读
    <b class='flag-5'>表达式</b>与逻辑门之间的关系

    C语言的表达式

    在C语言中,表达式是由操作符和操作数组成。表达式可以由一个或者多个操作数组成,不同的操作符与操作数组成不同的表达式,因此,表达式才是C语言的基本。
    的头像 发表于 02-21 15:09 952次阅读
    C语言的<b class='flag-5'>表达式</b>

    逻辑运算符与表达式

    在C语言中,我们通常会进行真值与假值的判断,这时我们就需要用到逻辑运算符与逻辑表达式。如果表达式的值不为0,则通通返回为真值。只有当表达式的值为0时,才会返回假值。
    的头像 发表于 02-21 15:16 1443次阅读
    逻辑运算符与<b class='flag-5'>表达式</b>

    Python中的Lambda表达式

    在 Python 中,Lambda 表达式是一种非常强大的工具,它可以让你快速创建小型匿名函数,而不需要显式地定义函数名称。Lambda 表达式通常用于传递函数对象或简单的函数式编程。
    的头像 发表于 04-19 15:49 521次阅读

    shell脚本基础:正则表达式grep

    在Linux上有许多命令可以使用正则表达式,其中最常见的是grep命令和sed命令。正则表达式有多种类型,每种类型中可以使用的元字符类型不同。最常见的是基本正则
    的头像 发表于 05-29 09:29 775次阅读
    shell脚本基础:正则<b class='flag-5'>表达式</b>grep

    一文详解Verilog表达式

    表达式由操作符和操作数构成,其目的是根据操作符的意义得到一个计算结果。表达式可以在出现数值的任何地方使用。
    的头像 发表于 05-29 16:23 1939次阅读
    一文详解Verilog<b class='flag-5'>表达式</b>

    zabbix触发器表达式 基本RS触发器表达式 rs触发器的逻辑表达式

    zabbix触发器表达式 基本RS触发器表达式 rs触发器的逻辑表达式  Zabbix是一款开源的监控软件,它能通过监控指标来实时监测服务器和网络的运行状态,同时还能提供警报和报告等功能来帮助管理员
    的头像 发表于 08-24 15:50 1213次阅读

    怎么去选择使用gm的三种表达式呢?

    我们在写跨导gm的表达式时,知道gm有三种表达式表达式含有的变量其实只有三个,一个W/L,一个Vgs-Vth,还有一个Id。
    的头像 发表于 09-17 15:31 3098次阅读
    怎么去选择使用gm的三种<b class='flag-5'>表达式</b>呢?

    linux正则表达式匹配字符串

    在Linux操作系统中,正则表达式是一种强大的模式匹配工具,它可以用于在文本中查找、替换和筛选特定的字符串。准确掌握正则表达式的语法和常见应用,对于Linux系统的管理员和开发人员来说
    的头像 发表于 11-23 10:26 335次阅读