java8新特性学习二(函数式functional接口)

Posted 马宝云

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8新特性学习二(函数式functional接口)相关的知识,希望对你有一定的参考价值。

函数式(functional)接口

 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。

可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。

我们可以在一个接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口。同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。

 

在java 8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。

在java.util.function包下定义了java 8的丰富的函数式接口。

 java内置四大核心函数式接口

 其他接口

 方法引用与构造器引用

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!

方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。

要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!

格式:使用操作符“::”将类(或对象)与方法名分隔开来。

如下三种主要使用情况

情况一,对象::实例方法名

    @Test
    public void test1(){
        //Consumer<T>    void accept(T t)
        //PrintStream    void printlt(T t)
        Consumer<String> consumer1=s-> System.out.println(s);
        consumer1.accept("测试一");

        System.out.println("************************");

        PrintStream printStream=System.out;
        Consumer<String> consumer2=printStream::println;
        consumer1.accept("方法引用情况一测试");

        System.out.println("--------------------------");
        //Supplier<T>    T get()
        //User           String toString()
        User user=new User("1001","张三",25,"成都");
        Supplier<String> supplier1=()-> user.toString();
        System.out.println( supplier1.get());

        System.out.println("************************");

        Supplier<String> supplier2=user::toString;
        System.out.println( supplier2.get());
    }

User类

public class User {
    private String id;
    private String name;
    private Integer age;
    private String address;

    public User(String id, String name, Integer age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public User() {
        System.out.println("user无参构造");
    }

    public User(String id) {
        this.id = id;
        System.out.println("id构造=="+id);
    }

    public User(String name,Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("name,age构造=="+name+"=="+age);
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age &&
                Objects.equals(id, user.id) &&
                Objects.equals(name, user.name) &&
                Objects.equals(address, user.address);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age, address);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=\'" + id + \'\\\'\' +
                ", name=\'" + name + \'\\\'\' +
                ", age=" + age +
                ", address=\'" + address + \'\\\'\' +
                \'}\';
    }
}

情况二,类::静态方法名

    @Test
    public void test2(){
        //Comparator<T>  int compare(T o1, T o2);
        //Integer     public static int compare(int x, int y)
        Comparator<Integer> com1=(t1,t2)->Integer.compare(t1,t2);
        System.out.println(com1.compare(11,22));

        System.out.println("*******************");

        Comparator<Integer> com2=Integer::compare;
        System.out.println(com1.compare(33,22));

        System.out.println("----------------");
        //Function<T,R>  R apply(T t);
        //Math    public static long round(double a)
        Function<Double,Long> func=new Function<Double, Long>() {
            @Override
            public Long apply(Double d) {
                return Math.round(d);
            }
        };
        System.out.println(func.apply(3.2d));

        System.out.println("********************");

        Function<Double,Long> fun1=d->Math.round(d);
        System.out.println(fun1.apply(2.72d));

        System.out.println("********************");

        Function<Double,Long> fun2=Math::round;
        System.out.println(fun2.apply(0.5d));
    }

情况三,类::实例方法名(有难度)

 @Test
    public void test3(){
        //Comparator<T>  int compare(T t1, T t2);
        //String   t1.compareTo(t2)
        Comparator<String> com1=(t1,t2)->t1.compareTo(t2);
        System.out.println(com1.compare("acd","abd"));

        System.out.println("********************");

        Comparator<String> com2=String::compareTo;
        System.out.println(com1.compare("abd","abf"));

        System.out.println("-------------");
        // BiPredicate  boolean test(T t1, T t2)
        //String  boolean t1.equals(t2)
        BiPredicate<String,String> pre1=(s1,s2)->s1.equals(s2);
        System.out.println(pre1.test("abc","abc"));

        System.out.println("***************");

        BiPredicate<String,String> pre2=String::equals;
        System.out.println(pre2.test("abc","abc"));

        System.out.println("-----------------");
        //Function  R apply(T t)
        //User String toString()
        User user=new User("1001","张三",25,"成都");
        Function<User,String> func1=u->u.toString();
        System.out.println(func1.apply(user));

        System.out.println("**************");

        Function<User,String> func2=User::toString;
        System.out.println(func2.apply(user));

    }

构造器引用 

和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。

抽象方法的返回值类型即为构造器所属的的类的类型。

  @Test
    public void test4(){
        //Supplier   T get()
        //User中的空参构造器:User()
        Supplier<User> supplier1=new Supplier<User>() {
            @Override
            public User get() {
                return new User();
            }
        };
        System.out.println(supplier1.get());
        System.out.println("***************");

        Supplier<User> supplier2=()->new User();
        System.out.println(supplier2.get());
        System.out.println("***************");

        Supplier<User> supplier3=User::new;
        System.out.println(supplier3.get());

        System.out.println("------------");
        //Function中的R apply(T t)
        Function<String,User> func1=id->new User(id);
        System.out.println(func1.apply("1001"));

        System.out.println("************");

        Function<String,User> func2=User::new;
        System.out.println(func1.apply("1001"));

        System.out.println("---------------------");
        //BiFunction   R apply(T t,U u)
        BiFunction<String,Integer,User> func3=(name,age)->new User(name,age);
        System.out.println(func3.apply("张三",25));

        System.out.println("*************");

        BiFunction<String,Integer,User> func4=User::new;
        System.out.println(func4.apply("张三",25));
    }

数组引用

把数组看成是一个特殊的类,则写法与构造器引用一致。

@Test
    public void test5(){
        //Function R apply(T t)
        Function<Integer,String[]> fun1=length->new String[length];
        System.out.println(Arrays.toString(fun1.apply(5)));

        System.out.println("***************");

        Function<Integer,String[]> fun2=String[]::new;
        System.out.println(Arrays.toString(fun2.apply(5)));
    }

  

 

以上是关于java8新特性学习二(函数式functional接口)的主要内容,如果未能解决你的问题,请参考以下文章

java8新特性学习

java8新特性学习

Java8新特性学习笔记 Lambda表达式

java8新特性学习六(新时间日期API)

java8新特性学习六(新时间日期API)

Java8新特性学习笔记 Lambda表达式