java8新特性——函数式接口,方法,构造器,数组引用

Posted zsbenn

tags:

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

package functional;
/*
定义:如果一个接口里面只声明了一个函数,就称为函数式接口
lambda表达式的本质:作为函数式接口的实例,必须依赖一类特别的对象类型——函数式接口
                   所以用匿名实现类表示的都可以用lambda表达式来写
Java.util.function 下也定义了Java8的函数式接口

函数式接口           内置抽象类           作用
1.Consumer<T>:      void accept(T t)    消费型
2.Supplier<T>:      T get()             返回一个对应的T对象
3.Function<T,R>:    R apply(T t)        对T的对象做一些处理,返回另一个R对象
4.Predicate<T>:     boolean test(T t)   测试T对象是否满足要求

@author zsben
@create 2020-01-10 19:13
*/

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

//函数式接口注解
@FunctionalInterface
interface MyInterface{
    void method1();
}

public class FunctionalTest {

    //第一类:消费性函数式接口 Consumer<T>
    public void happyTime(double money, Consumer<Double> consumer){
        consumer.accept(money);
    }
    @Test
    public void test1(){
        //这种写法是实现了Consumer<Double>的匿名子类对象
        happyTime(500, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println(aDouble);
            }
        });

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

        //通过lambda表达式实现函数式对象
        happyTime(400,money -> System.out.println(money));
    }


    //第二类:断言型函数式接口Predicate<T>
    //根据给定的规则,过滤集合中的字符串,此规则由Predicate的方法决定
    public ArrayList<String> filterString(List<String >list, Predicate<String> pre){
        ArrayList<String> filterList = new ArrayList<>();

        for(String s:list){
            if(pre.test(s))
                filterList.add(s);
        }

        return filterList;
    }
    @Test
    public void test2(){
        List<String> list = Arrays.asList("北京","南京","天津","东京","西京");

        //把名字里带有京的留下来
        List<String> filterStrs = filterString(list, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("");
            }
        });
        System.out.println(filterStrs);

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

        //这里其实就是用lambda把Predicate里的test(s)实现了
        List<String> filterStrs1 = filterString(list, s -> s.contains(""));
        System.out.println(filterStrs1);
    }


}
package functional;
/*
方法引用:顾名思义就是引用一个方法
1.使用情景:当要传递给lambda体的操作,已经有实现的方法了,可以使用方法引用
2.方法引用:本质上就是lambda表达式,而lambda作为函数式接口的实例,
           所以方法引用,也是函数式接口的实例
3.使用格式:
    类::静态方法名
    类::非静态方法名
    对象::非静态方法名

4.使用要求:接口中的抽象方法形参列表和返回值的类型 与 方法引用的方法的形参列表,返回值都相同
@author zsben
@create 2020-01-10 19:58
*/

import org.junit.Test;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class MethodreferencesTest {

    //情景一:对象::实例方法
    //Consumer中的void accept(T t)
    //PrintStream 中的 void println(T t)
    @Test
    public void test1() {
        Consumer<String> con1 = str -> System.out.println(str);
        con1.accept("北京");

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

        //System.out其实是一个打印流对象,有println(String s)这个方法
        PrintStream ps = System.out;
        Consumer<String> con2 = ps::println;//con2引用ps的方法println
    }

    //Supplier中的get()
    //Employee中的String getName()
    @Test
    public void test2(){
        Employee emp = new Employee(1001,"Tom",23,5600);

        Supplier<String> sup1 = ()->emp.getName();
        System.out.println(sup1.get());

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

        Supplier<String> sup2 = emp::getName;
        System.out.println(sup2.get());
    }

    //情景二:类::静态方法
    //Comparator中的int compare(T t1,T t2)
    //Integer 中的int compare(T t1,T t2)
    @Test
    public void test3(){
        Comparator<Integer> com1 = (t1, t2) -> Integer.compare(t1,t2);
        System.out.println(com1.compare(1,2));

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

        Comparator<Integer> com2 = Integer::compare;
    }

    //Function中的 R apply(T t)
    //Math 中的long round(Double d)
    @Test
    public void test4(){
        Function<Double, Long> func1 = d -> Math.round(d);

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

        Function<Double, Long> func2 = Math::round;//这个函数的形参,返回值必须一致
    }

    //情况三: 类::非静态方法
    //这种情况需要从lambda表达式对应的形参中抽出一个参数来当成该类的实例对象,并通过这个类调用后面的方法
    //Comparator中的int compare(T t1,T t2)
    //String中int t1.compareTo(t2)
    @Test
    public void test5(){
        Comparator<String> com1 = (s1,s2)->s1.compareTo(s2);
        System.out.println(com1.compare("123", "321"));

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

        Comparator<String> com2 = String::compareTo;
        System.out.println(com2.compare("123", "321"));
    }
    //BiPredicate 中的boolean test(T t1,T t2)
    //String 中的boolean t1.equals(t2)
    @Test
    public void test6(){
        BiPredicate<String, String> pre1 = (s1,s2)->s1.equals(s2);
        System.out.println(pre1.test("abd","asd"));

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

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

    //Function 中的 R apply(T t)
    //Employee 中的 String getName();
    @Test
    public void test7(){
        Function<Employee,String> func1 = (emp)->emp.getName();
        System.out.println(func1.apply(new Employee(1, "zsben", 23, 25000)));

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

        Function<Employee,String> func2 = Employee::getName;
        System.out.println(func2.apply(new Employee(1, "zsben", 23, 25000)));
    }
}
package functional;

/*
1.构造器引用
       和方法引用类似,函数式接口的抽象方法的形参列表和构造器和形参列表一致
       抽象方法的返回值类型即为构造器所属的类的类型
2.数组引用
    把数组看成是一个特殊的类,则写法和构造器引用一致
@author zsben
@create 2020-01-10 22:05
*/

import org.junit.Test;

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

public class ConstructorTest {
    //构造器引用
    //Suppier中的T get()
    @Test
    public void test1(){
        Supplier<Employee> sup1 = () -> new Employee();
        System.out.println(sup1.get());

        Supplier<Employee> sup2 = Employee::new;
        System.out.println(sup2.get());
    }

    //Function中的R apply(T t)
    @Test
    public void test2(){
        Function<Integer,Employee> func1 = id -> new Employee(id);
        System.out.println(func1.apply(1));

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

        Function<Integer,Employee> func2 = Employee::new;
        System.out.println(func2.apply(1));
    }

    //BiFunction中的R apply(T t,U u)
    @Test
    public void test3(){
        BiFunction<Integer,String,Employee> func1 = (id,name)->new Employee(id,name);
        System.out.println(func1.apply(1,"zsben"));

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

        BiFunction<Integer,String,Employee> func2 = Employee::new;
        System.out.println(func1.apply(1,"zsben"));
    }

    //数组引用
    //Function中的R apply(T t)
    @Test
    public void test4(){
        Function<Integer,String[]> func1 = (length)->new String[length];
        String[] arr1 = func1.apply(6);
        System.out.println(Arrays.toString(arr1));

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

        Function<Integer,String[]> func2 = String[]::new;
        String[] arr2=func2.apply(1);
        System.out.println(Arrays.toString(arr1));
    }
}

以上是关于java8新特性——函数式接口,方法,构造器,数组引用的主要内容,如果未能解决你的问题,请参考以下文章

Java8新特性——Lambda表达式之四大核心函数式接口 & 方法/构造器/数组引用

Java8新特性:函数式接口,方法与构造器引用

Java8新特性函数式编程API新时间日期处理APIOptional容器类总结

Java8新特性函数式编程API新时间日期处理APIOptional容器类总结

Java8新特性函数式编程API新时间日期处理APIOptional容器类总结

Java8新特性函数式编程API新时间日期处理APIOptional容器类总结