Java8新特性系列二:Lambda和函数式接口

时间:2020-07-22 00:48:43   收藏:0   阅读:77

1. 函数式接口

 1. 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,可以有多个非抽象方法的接口

 2. 函数式接口可以被隐式转换为 lambda 表达式

 3. 函数式接口通常@FunctionalInterface注解标识

/**
 * 这是一个自定义的函数式接口
 * @FunctionalInterface 用于检测一个接口是否为函数式接口
 */
@FunctionalInterface
public interface MyInterface {
    boolean method();
}

2. Lambda表达式

 Lambda可以作为参数和返回值,此外匿名内部类没有class文件的概念,内存中即少加载一个文件
public class Lamda {

    public static void main(String[] args) {
        List<Apple> inventory = Arrays.asList(new Apple(100, "red"), new Apple(150, "green"));
        List<Apple> result = filter(inventory, apple -> apple.weight > 100);
        result.forEach(System.out::println);
    }

    public static List<Apple> filter(List<Apple> inventory, MyInterface iface) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (iface.method(apple)) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * 这是一个自定义的函数式接口
     *
     * @FunctionalInterface 用于检测一个接口是否为函数式接口
     */
    @FunctionalInterface
    public interface MyInterface {
        boolean method(Apple apple);
    }
}

2.1 Lambda延迟加载

 提升性能:有些代码在执行后,结果不一定被使用,从而造成性能浪费;例如:日志案例

public class LoggerLambda {

    public static void main(String[] args) {
        String msgA = "Hello ";
        String msgB = "world ";
        String msgC = "Java ";
        //只有level==1时,才会执行buildMessage(),返回拼接的字符串,不浪费性能
        log(1, () -> msgA + msgB + msgC);
    }

    private static void log(int level, MessageBuilder builder) {
        if (level == 1) {
            System.out.println(builder.buildMessage());
        }
    }

    @FunctionalInterface
    public interface MessageBuilder {
        String buildMessage(); //空参数,返回值为String
    }
}

2.2 Lambda作用域

在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量

3. 常用的API函数式接口

 JDK 1.8 之前

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

 JDK 1.8 之后 

3.1 Predicate

 java.util.function.Predicate<T>接口是判断型接口,返回值boolean;包含5个方法:

 1. boolean test(T t)

 2. default Predicate<T> and(Predicate<? super T> other)

 3. dafault Predicate<T> or(Predicate<? super T> other)

 4. default Predicate<T> negate()

 5. static <T> Predicate<T> isEqual(Object targetRef)

 

Supplier接口

 java.util.function.Supplier<T>接口是供给型接口,包含一个无参的方法:T get()获取泛型参数指定类型的对象;<T>接口是什么类型,T get()就返回什么类型;

这就意味这Lambda表达式需要对外提供一个符合泛型类型的对象数据;个人理解:Supplier类似于工厂,提供了一个规范,用户DIY具体实现,Suppiler<User>等;

技术分享图片

Consumer接口

java.util.function.Consumer<T>接口是消费型接口,与Suppier接口相反;包含两个方法:

 1. void accept(T t)

 2. default Consumer<T> andThen(Consumer<? super T> after)

技术分享图片

 

技术分享图片

Function接口

java.util.function.Function<T,R>接口用来转化数据类型,T, R表示接口输入、输出的数据类型;包含4个方法:

1. R apply(T t)

2. default <V> Function<T, V> andThen(Function<? super R, ? extends V> after)

3. default <V> Function<V, R> compose(Function<? super V, ? extends T> before)

4. static <T> Function<T, T> identity()

技术分享图片

BiFunction接口

java.util.function.Function<T,U,R> 接口用来转化数据类型,T, U表示接口输入的数据类型、R表示输出的数据类型;包含2个方法:

1. R apply(T t, U u);

2. default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after)

原文:https://www.cnblogs.com/oxygenG/p/13357943.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!