美文网首页
Java8(一)之走近Lamda

Java8(一)之走近Lamda

作者: 依然范特希 | 来源:发表于2019-04-30 17:13 被阅读0次

高阶函数

了解Lamda表达式之前,我们先来了解一下什么是高阶函数。
在数学和计算机领域中,高阶函数是至少满足以下两个条件中一个:
1.接受一个或多个函数作为输入
2.输出一个函数

为什么使用Lamda

相信大家除了Java语言也接触过类似于JavaScript或者Scala等脚本语言,这些语言是支持高阶函数的,也大都同时满足以上的两点。Scala语言本身就依赖于JVM,所以对于Java语言实现高阶函数也是完全,没有问题的。在JDK8中,Lamda表达式就是专门来实现Java的函数式编程。
可能有一些小伙伴还没有太多的使用JDK8的版本,就会想Lamda表达式能给我们带来什么呢?代码的简化以及可读性,Lamda表达式加链式调用会让代码看起来通俗易懂。话不多说,先看一个简单的栗子吧~

        // JDK8之前的代码
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread run!!!");
            }
        }).start();
        // Lamda表达式的代码
        new Thread(()->{System.out.println("thread run!!!");}).start();

在代码上的整洁程度来说显而易见,如果有了Lamda表达式我们很大程度上就可以告别恶心的匿名内部类(思考一下匿名内部类的特质,比如变量的可见性,Lamda表达式是怎样的,需要遵守么),尤其是有多次调用的情况,可以通过链式调用来表达,更加的条理和人性化。

如何申明一个Lamda表达式接口

1.申明一个接口,加入类注解@FunctionalInterface,保证接口中未实现的方法有且只有一个,接口默认方法不计算在内,如果不信的话,你可以试试,多个的话就会编译报错(这里需要思考一下为什么是一个,我个人觉得这里是Java为了实现函数式编程进行了“强扭的瓜”,的确是不太“甜”,内部的实现应该还是内部类的逻辑,这里是猜测)

@FunctionalInterface
public interface LamdaInterface {
    
    public String apply(String name);
    
    // 默认函数可以有
    default String addLastName(String name) {
        return apply(name) + "Curry";
    }

}

2.完成需要完成逻辑,就像填空题一样,所有的内容都完成了,只留下一个需要空来填,这要填的空就是要实现的函数逻辑。

public class NBAPlayer {
    
    public String firstName;

    // 具体结果还要依赖于接口方法的实现。这里就是我们要填的空
    public void printName(LamdaInterface lamdaInterface) {
        System.out.println(lamdaInterface.addLastName(this.firstName));
    }

}
  1. 根据Lamda表达式实现内容
    public static void main(String[] args) throws Exception{
        NBAPlayer nbaPlayer = new NBAPlayer();
        nbaPlayer.firstName = "Stephen";
        nbaPlayer.printName(name->name+"·");
    }

完整的步骤需要这三步,看到这里小伙伴们是不是觉得我忽悠你们了,这个写的代码感觉也不是很少呀,还是很痛苦。其实在实际开发的过程中,第1步是不需要我们自己做的,JDK在java.util.function包下有很多实例,涵盖了大部分的情况,所以不需要自己写函数式接口。大部分情况下第2步也是不需要自己做,因为大部分情况下都是去调用第三方的jar,这部分逻辑都已经实现,如果在一个团队中不是基础平台的开发人员的话,这一步接触的也比较少一点。所以对于我们来说其实只要把第三步完全掌握了就OK了。下面我们看一下JDK给我们提供的常见的函数式接口。

JDK提供的函数式接口

  1. Talk is cheap,show the code.
@FunctionalInterface
public interface Consumer<T> {
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> var1) {
        Objects.requireNonNull(var1);
        return (var2) -> {
            this.accept(var2);
            var1.accept(var2);
        };
    }
}
  1. Talk is cheap,show the code.
@FunctionalInterface
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;
    }
}
  1. Talk is cheap,show the code.
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T var1);

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

    default Predicate<T> negate() {
        return (var1) -> {
            return !this.test(var1);
        };
    }

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

    static <T> Predicate<T> isEqual(Object var0) {
        return null == var0 ? Objects::isNull : (var1) -> {
            return var0.equals(var1);
        };
    }
}
  1. Talk is cheap,show the code.
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

上面的四种是我个人认为很常用的四种,就把JDK源码列出来了,大家看代码就好了,如果还需要其他形式的,建议先去java.util.function包下找一下,如果没有的话,再自己去新建。第一步搞定了,第二部其实主要就是实现的逻辑,没啥好说的,接下来看第三步的写法。

Lamda表达式常见写法

公共代码,下面会用到

@FunctionalInterface
interface inter1 {
    String said(String sm);
}

@FunctionalInterface
interface inter2{
    Employee getEmployee(String name, String address, int salary, int age);
}

class Robot{
    
    public String robotGun;
    
    public void attack (inter1 inter1) {
        String attack = inter1.said(robotGun);
        System.out.println(attack);
    }
}

class Attack{
    public static String attack(String said) {
        return "Attack!!!!!!!" + said;
    }
    
    public  String shot(String said) {
        return "Shot!!!!!!!" + said;
    }
    
    public Employee getEmployee(inter2 inter2,String name, String address, int salary, int age) {
        return inter2.getEmployee(name, address, salary, age);
    }
}
  1. 无参数,必须加括号,如果方法体的内容就一句话其实是可以不加花括号的
        Thread thread = new Thread(() -> {System.out.println(1);});
        thread.start();

2.一个参数,一个参数方法头可以省略括号

        Robot robot = new Robot();
        robot.robotGun = "AWM";
        robot.attack(said ->  said + " attack!");

3.多个参数,如果体部是一句话以上的必须加花括号

        List<Integer> list = Arrays.asList(99,55,66,88);
        Collections.sort(list, (x,y) -> x - y);
        for(Integer num : list) {
            System.out.println(num);
        }

4.引用静态方法

        Attack attack = new Attack();
        robot.attack(Attack::attack);

5.引用实例对象方法

        robot.attack(attack::shot);

6.引用构造方法

        inter2 inter2 = Employee :: new;
        Employee employee = attack.getEmployee(inter2, "xusq", "shanxi", 30000, 18);
        System.out.println(employee.toString());

以上我列出来的常见的Lamda表达式的写法,如果觉得不是很懂的话,就都忘了吧,你只需要记住,我们要传入的是一个函数就ok了,静态方法,成员方法,构造方法都是方法,只要是方法就去试试。
Lamda表达式的学习就到这里了,希望这篇文章能够帮助到一些小伙伴。求真至善,登崇俊良。我们下一期再见。

相关文章

  • Java8(一)之走近Lamda

    高阶函数 了解Lamda表达式之前,我们先来了解一下什么是高阶函数。在数学和计算机领域中,高阶函数是至少满足以下两...

  • 2020-03-19-Java8使用Lamda代替字符串

    layout: posttitle: Java8使用Lamda代替字符串categories: [Java]des...

  • Java8函数式编程的方法引用

    本文参考: 《30分钟入门Java8之方法引用》方法引用,一般有四种形式: 引用构造方法 等价于Lamda表达式 ...

  • java8的lamda表达式

    Java中的lamda表达式通常使用的是(argument)->(body)语法格式。例如:java8之前的run...

  • java8Lambda表达式如何使用

    java8Lambda表达式如何使用 lamda表达式是java8新特性,优点简化代码,降低代码重复率。 语法格式...

  • Java8之Stream流(六)收集

    Java8之Stream流(一)基础体验 Java8之Stream流(二)关键知识点 Java8之Stream...

  • 2021-03-29Java 8 概述

    java8 的新特性:Java是oracle公司在2014年3月18日发布的1.支持Lamda表达式2.函数式接口...

  • Java 统计字符串中重复字符的个数

    每日一经 每天收集一个java日常能用到的解决问题的方法,以后方便查阅。 实现 java8 环境,使用了lamda表达式

  • Java8 Lamda表达式

    目的 提供更能表达代码意图的方法。 表达式的目标类型 函数接口类型 适用对象 具有单个抽象方法和0个或0个以上非抽...

  • 函数指针

    lamda传入函数指针 如果带捕获参数则不能传入。 lamda [&] 和 [=] reuslt: 113 所以一...

网友评论

      本文标题:Java8(一)之走近Lamda

      本文链接:https://www.haomeiwen.com/subject/nfevnqtx.html