美文网首页
Java8 函数式接口 学习笔记

Java8 函数式接口 学习笔记

作者: R7_Perfect | 来源:发表于2020-11-26 15:22 被阅读0次

一, 函数式编程

java中的函数式编程体现就是Lambda和方法引用:

Lambda

// 1.1使用匿名内部类  
new Thread(new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello world !");  
    }  
}).start();  
  
// 1.2使用 lambda 获得Runnable接口对象  
new Thread(() -> System.out.println("Hello world !")).start();

Lambda除了简洁之外,还具有延迟执行特点

延迟执行

有些场景的代码执行后,结果不一定会被使用,从而造成性能浪费。而Lambda表达式是延迟执行的,这正好可以作为解决方案,提升性能。

public class Demo01Logger {
    private static void log(int level, String msg) {
        if (level == 1) {
            System.out.println(msg);
        }
     }
    public static void main(String[] args) {
        String msgA = "Hello";
        String msgB = "World";
        String msgC = "Java";
        log(2, msgA + msgB + msgC);//级别1 不一定能够满足 但是 字符串连接操作还是执行了 那么字符串的拼接操作就白做了,存在性能浪费
    }
}

Lambda的更优写法:

@FunctionalInterface
public interface MessageBuilder {
    String buildMessage();
}
public class Demo02LoggerLambda {
    private static void log(int level, MessageBuilder builder) {
        if (level == 1) {
            System.out.println(builder.buildMessage());// 实际上利用内部类 延迟的原理,代码不相关 无需进入到启动代理执行
        }
    }
    public static void main(String[] args) {
        String msgA = "Hello";
        String msgB = "World";
        String msgC = "Java";
       log(2,()->{
                System.out.println("lambda 是否执行了");
                return msgA + msgB + msgC;
        });
    }
}

方法引用

方法引用,不是方法调用!
方法引用是 lambda 表达式的语法糖,任何用方法引用的地方都可由lambda表达式替换

list.forEach(value -> System.out.println(value));

可替换为

list.forEach(System.out::println);
类别 使用形式
静态方法引用 类名 :: 静态方法名
实例方法引用 对象名(引用名) :: 实例方法名
类方法引用 类名 :: 实例方法名
构造方法引用 类名 :: new

二, 函数式接口

定义:函数式接口(Functional Interface):有且仅有一个抽象方法的接口,但可以有多个非抽象方法的接口

  • 你可以通过 Lambda 表达式或方法引用来创建该接口的对象。
  • 可以在任意函数式接口上使用 @FunctionalInterface 注解,这样做可以检测它是否是一个函数式接口

@FunctionalInterface

在JDK 8中引入了FunctionalInterface接口,其源代码定义如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

加上@FunctionalInterface标注,则会触发JavaCompiler的检查。对于符合函数接口的接口,加不加都无关紧要,但是加上则会提供一层编译检查的保障。如果不符合,则会报错。

需要注意的是:接口中只能存在一个抽象方法
格式:

修饰符 interface 接口名称{
    public abstract 返回值 方法名称(参数列表)
    // 其他方式 
}
// public abstract 可以不写 编译器自动加上
修饰符 interface 接口名称{
       返回值 方法名称(参数列表)
    // 其他方式 
}

调用举例:

@FunctionalInterface // 标明为函数式接口
public abstract MyFunctionInterface{
    void method(); //抽象方法
}

public class TestFunctional {
    // 定义一个含有函数式接口的方法
    public static void doSomething(MyFunctionInterface functionalInterface) {
        functionalInterface.method();//调用自定义函数式接口的方法
    }
    public static void main(String[] args) {
        //调用函数式接口的方法
        MyFunctionInterface functionalInterface = () -> System.out.println("hello!")
        doSomething(functionalInterface );
    }
}

常用函数式接口

接口 参数 返回值 说明
Supplier<T> T 供给型;无参,返回一个指定泛型的对象
Consumer<T> T 消费型;传入一个指定泛型的参数,无返回值
Predicate<T> T Boolean 断言型;判断函数,返回判断结果true/false
Function<T,R> T R 方法型;输入一个参数,得到一个结果

Supplier

无参有返回值

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

使用:

public class TestSupplier {
    public static void main(String[] args) {
         // 产生的数据作为 sout 作为输出
        Supplier<String> supply = ()->"产生数据"
        System.out.println(supply.get());//输出“产生数据”
    }
}

Consumer

有参无返回值

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
    ...
}

使用:

public class TestComsumer {
    public static void main(String[] args) {
        Consumer<String> consumer = s->System.out.println(s)
        consumer.accept("hello");//输出“hello”
    }
}

Predicate

对入参数据进行判断,并返回boolean

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
    ...
}

使用:

public class UsePredicate {
    public static void main(String[] args) {
        Predicate<Integer> predicate = (x)-> x==10;
        System.out.println(predicate.test(10));//输出true
    }
}

Function

将入参T转为返回值R

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

使用:

// 将数字转换为String类型
private static void numberToString() {
    String apply = function.apply(12);
    System.out.println("转换结果:"+apply);
}
public static void main(String[] args) {
        Function<Number, String> function = (s)->String.valueOf(s)
    System.out.println("转换结果:"+function.apply(12));//输出“12”
}

三, Functional Java

Functional Java是一个第三方库,是一个在Java语言中实现函数型编程范式的类库。

标准的Java 8 也引入了很多函数型编程范式的元素,比如Stream,lambda以及函数型接口。但在功能上Java 8 远不如Functional Java丰富,使用上也受到一定的限制。

Functional 项目地址:https://github.com/functionaljava/functionaljava

引入

//主包
compile "org.functionaljava:functionaljava:4.8"
//可以不引入
compile "org.functionaljava:functionaljava-java8:4.8"
compile "org.functionaljava:functionaljava-quickcheck:4.8"
compile "org.functionaljava:functionaljava-java-core:4.8"

F0, F, F2, …, F8

对应Fuction<T,R>类, F<A, B>输入类型为A,返回值类型为B
F0没有入参,F有1个入参,…,F8有8个入参
返回值类型都只有一个,最后那个类型参数代表返回值类型。

F<Integer, Integer> twice = n -> n * 2;
F2<Integer, Integer, Integer> f = (a, b) -> a + b;
F3<Integer, Integer, Integer, Integer> g = (a, b, c) -> a + b + c;

Effect0, Effect1, Effect2, …, Effect8

没有返回值的函数接口类型, 对应Consumer
Effect0没有入参,Effect1有1个入参,…,Effect8有8个入参

Effect1<Integer> abc = n -> System.out.println(n);
FJ 接口 FJ 方法 Java 8 接口 Java 8 方法
Effect2<T, U> f BiConsumer<T, U> accept
F2<T, U, R> f BiFunction<T, U, R> apply
F2<T, T, T> f BinaryOperator<T> apply
F2<T, U, Boolean> f BiPredicate<T, U> test
F0<Boolean> f BooleanSupplier getAsBoolean

其他特性不多做介绍了。。。

相关文章

  • 函数式接口

    函数式接口 声明:java8新特性系列为个人学习笔记,参考地址点击这里,侵删!! 函数式接口(Functional...

  • JAVA8函数式接口学习

    JAVA8函数式接口 函数式接口是java8的一种新特性,函数式接口定义了且只定义了一个抽象方法!该接口非常有用,...

  • java8系列-02 函数式接口(Function、Consum

    上一章已经说了函数式接口的基本概念(java8系列-01 Lambdas 表达式)。函数式接口(Functiona...

  • Java8 函数式接口 学习笔记

    一, 函数式编程 java中的函数式编程体现就是Lambda和方法引用: Lambda Lambda除了简洁之外,...

  • JAVA8新特性之函数式接口使用与学习

    函数式接口 函数式接口是Java8引用的一个新特性,是一种特殊的接口 SAM类型的接口(Single Abstra...

  • Java8值函数式接口

    Java8值函数式接口 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口 在接口上声明@Functi...

  • java8 lambda

    java8 lambda 函数式接口 谓词 Predicate boolean test(T t); T -...

  • Java8学习笔记目录

    Java8学习笔记 -- 接口的默认方法与静态方法 Java8学习笔记 -- Lambda表达式,Function...

  • Lambda表达式

    Lambda表达式是Java8的一个新特性,是函数式接口的一种体现。所谓函数式接口(functional inte...

  • 函数式接口(二)

    前面的文章中说明了Java8中最基本的4种函数式接口,我们今天先介绍其它Cosumer函数式接口。 BiConsu...

网友评论

      本文标题:Java8 函数式接口 学习笔记

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