我的位置:首页 > Java开发>Java web

Lamda表达式学习笔记一

时间:2020-02-07 18:44:00 来源:互联网 作者: 神秘的大神 字体:

                          Lamda表达式学习笔记一

一、Lamda语法诠释

  三傻大闹宝莱坞的主人公兰彻说的一句话让我映像深刻:用简单的语言来表达同样的意

我并不是说书上的定义怎么怎么不对,而是应该理解书本上的定义,并用简单的话语描述!

那么正题来了,lamda表达式是什么?

定义:lamda表达式是一个可传递的代码块,可以在以后执行一次或多次(将代码像数据一样进行传输)。

可传递的代码块?匿名内部类就是一种代码块!

 1 /**
 2      * 普通匿名函数
 3      */
 4     @Test
 5     public void test() {
 6         Comparator<Integer> comparator = new Comparator<Integer>() {
 7             @Override
 8             public int compare(Integer x, Integer y) {
 9                 return Integer.compare(x, y);
10             }
11         };
12         TreeSet<Integer> ts = new TreeSet<>(comparator);
13     }
14 
15     /**
16      * lamda表达式
17      */
18     @Test
19     public void test1() {
20         Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
21         TreeSet<Integer> ts = new TreeSet<>(comparator);
22     }

证明了lamda语法确实能代替匿名函数,也就意味着lamda表达式需要接口的支持。

 

需要怎么样的接口来支持lamda表达式呢?这个问题我们后面再说。

 

二、Lamda语法

  分别是

  1. 参数列表
  2. lamda符号
  3. lamda体,接口抽象方法的实现

此处的参数列表是接口中抽象方法的形参,lamda体则是对于接口抽象方法的实现,那我们写lamda表达式用接口中哪一个方法?这个问题,jvm是不知道的,所以我们需要的接口就是只有一个抽象方法的接口

函数式接口:只有一个抽象方法的函数,通常函数式接口用@FunctionInterface来声明

 

三、lamda表达式的表现形式

lamda表达式的4种形式

  1. 无参->无返回值

/**
     * 无参->无返回值
     */
    @Test
    public void test2() {
        Runnable runnable = () -> System.out.println("hahahah");
        runnable.run();
    }

    2.无参->有返回值

/**
     * 无参->有返回值
     */
    @Test
    public void test3() {
        Supplier<Integer> consumer = () -> 10;
        Integer o = consumer.get();
        System.out.println(o);
    }

 

    3.有参->无返回值

/**
     * 有参->无返回值
     */
    @Test
    public void test4() {
        Consumer consumer = (x) -> System.out.println();
        consumer.accept("hahahah");
    }

 

         4.有参-有返回值

/**
     * 有参->有返回值
     */
    @Test
    public void test5() {
        Function<Integer, Integer> function = (x) -> x * x;
        System.out.println(function.apply(1000));
    }

 

四、四大内置函数式接口

这四个接口分别是:Consumer<T>,Supplier<T>,Function<T, R>,Predicate<T>

  1.Consumer<T> 消费型接口

@FunctionalInterface
public interface Consumer<T> {
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            this.accept(t);
            after.accept(t);
        };
    }
}

 

  2.Supplier<T>   供给型接口

package java.util.function;

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

 

  3.Function<T, R>  功能型接口

import java.util.Objects;

@FunctionalInterface
public interface Function<T, R> {
    R apply(T var1);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (v) -> {
            return this.apply(before.apply(v));
        };
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            return after.apply(this.apply(t));
        };
    }

    static <T> Function<T, T> identity() {
        return (t) -> {
            return t;
        };
    }
}

 

  4.Predicate<T>  断言型接口(函数返回值是boolean值)

package java.util.function;

import java.util.Objects;

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T var1);

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

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

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

    static <T> Predicate<T> isEqual(Object targetRef) {
        return null == targetRef ? Objects::isNull : (object) -> {
            return targetRef.equals(object);
        };
    }

    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return target.negate();
    }
}

 

不仅仅有这4个函数型接口,java8还为我们提供了

 

最后针对lamda表达式含有3个地方可以优化

1.当只有一个参数时可以不写小括号

2.当lamda体中只有一条语句时可以不用加大括号

3.参数列表可以不用声明参数类型,jvm会根据上下文来分析数据类型(不需要考虑性能问题,因为不论如何我们的.java代码都会进行编译)

侵删,文章仅供大家交流学习,第一次写文章,有不足之处希望大家多多包涵

参考: https://www.bilibili.com/video/av62117143