美文网首页
lambda表达式之方法的引用(重点)

lambda表达式之方法的引用(重点)

作者: 金石_832e | 来源:发表于2019-08-05 17:28 被阅读0次

方法的引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而并不执行方法的方式,如果抽象方法的实现恰好可以使用调用另一种方法来实现,就有可能可以使用方法引用。


方法的引用分为四种类型

静态方法引用
实例方法引用
对象方法引用
构造方法引用


静态方法引用

如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用。

package com.per.lambada;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
class Foo{
    public static String ret() {
        System.out.println("put method invoke");
        return "ret hello";
    }
    
    public static void con(int size) {
        System.out.println("size:"+size);
    }
    static String fun(String str) {
        return str.toUpperCase();
    }
}
public class Test{
    public static int put() {
        return 23;
    }
    
    public static void main(String[] args) {
        
        // 调用本类中的静态方法的引用
        Supplier<Integer> s= ()->Test.put();
        
        // 可以简化成::
        Supplier<Integer> s1= Test::put;
        
        // 调用非本类中的静态方法的引用
        Supplier<String> s2=Foo::ret;
        
        System.out.println(s.get());
        
        System.out.println(s2.get());
        
        // 有参无返回值
        Consumer<Integer> con1 = size -> Foo.con(size);
        Consumer<Integer> con2 = Foo::con;
        con2.accept(100);
        
        // 有参有返回值
        Function<String,String> fun1 = str -> Foo.fun(str);
        Function<String,String> fun2 = Foo::fun;
        System.out.println(fun2.apply("zhangsan"));
    }
}

23
put method invoke
ret hello
size:100
ZHANGSAN


实例方法的引用

如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用
Example3 .java

package com.edu.java8.lambda;

import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 实例方法引用
 * 如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用
 * 
 *  语法
 *  inst::instMethod
 */
public class Example3 extends Base {

    public String put() {
        return "hello";
    }
    
    public void con(Integer size) {
        System.out.println("size : " + size);
    }
    
    public String toUpper(String str) {
        System.out.println("current to upper");
        return str.toUpperCase();
    }
    
    public void test() {
        Function<String, String> f4 = this::toUpper;
        System.out.println(f4.apply("javame"));
        
        Function<String, String> f5 = super::toUpper;
        System.out.println(f5.apply("javame"));
    }
    
    public static void main(String[] args) {
        Supplier<String> s = () -> new Example3().put();
        Supplier<String> s1 = () -> {return new Example3().put();};
        Supplier<String> s2 = new Example3()::put;
        System.out.println(s2.get());
        
        Example3 exam = new Example3();
        exam.test();
        
        Consumer<Integer> c1 = (size) -> new Example3().con(size);
        Consumer<Integer> c2 = new Example3()::con;
        Consumer<Integer> c3 = exam::con;
        c2.accept(100);
        c3.accept(100);
        
        Function<String, String> f1 = str -> str.toUpperCase();
        Function<String, String> f2 = str -> exam.toUpper(str);
        Function<String, String> f3 = str -> new Example3().toUpper(str);
        Function<String, String> f4 = exam::toUpper;
        Function<String, String> f5 = new Example3()::toUpper;
        System.out.println(f4.apply("javase"));
        System.out.println(f5.apply("javaee"));
    }

}

Base.java

public class Base {

    public String toUpper(String str) {
        System.out.println("base to upper");
        return str.toUpperCase();
    }
}

在实例方法引用中是可以使用this和super关键字的。


对象方法的引用

抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以适用对象方法引用。

package com.edu.java8.lambda;

import java.io.Closeable;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 对象方法引用
 * 抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。
 * 如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用
 * 
 * 
 * 第一个参数类型 最好是自定义的类型
 * 
 *  语法
 *  类名::instMethod
 */
public class Example4 {
    
    /**
     * 抽象方法没有输入参数,不能使用对象方法引用
     * 比如说,如下函数式接口
     */
    public void not() {
        Runnable run = () -> {};
        Closeable c = () -> {};
        Supplier<String> s = () -> "";
    }
    
    public static void main(String[] args) {
        Consumer<Too> c1 = (Too too) -> new Too().foo();
        Consumer<Too> c2 = (Too too) -> new Too2().foo();
        Consumer<Too> c3 = Too::foo;
        
        c1.accept(new Too());
        c3.accept(new Too());
        
        BiConsumer<Too2, String> c5 = (too2, str) -> new Too2().fo(str);
        BiConsumer<Too2, String> c6 = Too2::fo;
        
        BiFunction<Prod, String, Integer> bf1 = (p, s) -> new Prod().fun(s);
        BiFunction<Prod, String, Integer> bf2 = (p, s) -> new Too().fun(s);
        BiFunction<Prod, String, Integer> bf3 = Prod::fun;
        
        Execute ex1 = (p,name,size) -> new Prod().run(name, size);
        Execute ex2 = Prod::run;
    }

}

interface Execute {
    public void run(Prod p, String name, String size);
}

class Prod {

    public void run(String name, String size) {
        
    }
    
    public Integer fun(String s) {
        return 1;
    }
    
}

class Too {
    public Integer fun(String s) {
        return 1;
    }
    
    public void foo() {
        System.out.println("invoke");
    }
}

class Too2 {
    
    public void foo() {
        System.out.println("invoke");
    }
    
    public void fo(String str) {
        
    }
}

构造方法的引用

如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用

package com.edu.java8.lambda;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 构造方法引用
 * 如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用
 * 
 * 
 *  语法
 *  类名::new
 */
public class Example5 {
    
    public static void main(String[] args) {
        Supplier<Person> s1 = () -> new Person();
        Supplier<Person> s2 = Person::new;
        s1.get();
        s2.get();
        
        Supplier<List> s3 = ArrayList::new;
        Supplier<Thread> s4 = Thread::new;
        Supplier<Set> s5 = HashSet::new;
        Supplier<String> s6 = String::new;
        
        Consumer<Integer> c1 = (age) -> new Account(age); 
        Consumer<Integer> c2 = Account::new;
        c2.accept(123);
        
        Function<String, Integer> fu = (str) -> Integer.valueOf(str);
        Function<String, Integer> fu1 = Integer::valueOf;
        
        Function<String, Account> fu2 = (str) -> new Account(); 
        Function<String, Account> fu3 = Account::new;
        fu3.apply("admin");
    }

}

class Account {
    public Account() {
        System.out.println("Account");
    }
    public Account(int age) {
        System.out.println("Account(age)");
    }
    public Account(String name) {
        System.out.println("Account(name)");
    }
}

class Person {
    public Person() {
        System.out.println("new Person()");
    }
}

相关文章

  • Java8学习笔记--Lambda表达式,Functional接

    主要内容 Lambda表达式 Functional接口 方法引用 1.Lambda表达式 Lambda表达式这个新...

  • jdk1.8新特性

    目录: 1. LAMBDA表达式(重点) 2. 函数式接口 3. 方法引用于构造器引用 4. Stream API...

  • java8

    1.lambda表达式《java8 Lambda表达式简介》 《java8 lambda表达式,方法的引用以及构造...

  • JAVA新特性总结

    Lambda 表达式− Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。 方法引用− 方法引用...

  • JDK1.8新增特性参考

    Lambda表达式 Stream函数式操作流元素集合 接口新增:默认方法与静态方法 方法引用,与Lambda表达式...

  • lambda表达式之方法的引用(重点)

    方法的引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而并不执行方法的方式,如果抽...

  • JAVA 8 新特性

    1.JAVA 8 新特性 Lambda表达式:Lambda允许把函数作为一个方法的参数; 方法引用:方法引用提供了...

  • Java8

    lambda表达式与方法引用 lambda表达式 一般形式: (a,b)->a+b; (a,b)->{ st...

  • java8 之方法引用

    方法引用 你可以使用lambda表达式来创建匿名方法。 但是,有时,lambda表达式只是仅仅调用一个方法。在这些...

  • Java 函数式编程技能清单

    首先,了解匿名内部类,函数式接口1、熟练使用Lambda表达式编程掌握Lambda表达式编写方法,方法引用,默认方...

网友评论

      本文标题:lambda表达式之方法的引用(重点)

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