java8内置四大函数&方法引用与构造器引用

为了免去用户每次使用Lambda表达式时,都自行创建函数式接口,Java提供了4大核心内置函数式接口

* Consumer<T> :消费型接口

* void accept(T t);

*

*Supplier<T> :供给型接口

* T get();

*

*Function<T,R> :函数型接口

* R apply(T t);

*

*Predicate<T> :断言型接口

1.代码实现

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

public class Jdk_Interface_Test {
        public static void main(String[] args){
//              test1();
                test2();
        }
        //Consumer<T> 消费型接口:void accept(T t);
        public static void test1(){
               happy(1000,(m) ->System.out.println("喜欢大宝剑,消费:"+m+"元"));
        }
        public static void happy(double money,Consumer<Double> con){
            con.accept(money);//传入一个money,没有返回值,直接消费
        }
        
    //Supplier<T> 供给型接口: 需求:产生指定个数的整数,并放入集合中:   T get();
    private static void test2(){
        List<Integer> numList=getNumList(3, ()->(int)(Math.random()*100));
        for (Integer num : numList) {
            System.out.println(num);
        }
        
        //内部类
                 List<Integer> numList2=getNumList(10, new Supplier<Integer>() {
                 public Integer get(){
                                 return (int)(Math.random()*100);
                         }
                });
                 
    }
    private static List<Integer> getNumList(int num,Supplier<Integer> sup){
        List<Integer> list=new ArrayList<>();
        for (int i = 0; i < num; i++) {
            Integer n = sup.get();//n为返回值,返回一个整数,以上来说,就是返回一个随机数,添加到list,然后遍历list
            list.add(n);
        }
        return list;
    }

    //Function<T,R> 函数型接口:R apply(T t);
    private static void test3(){
        String newStr = strHandler("\t\t\t 啦啦啦德玛西亚  ", (str)->str.trim());
        System.out.println(newStr);

        String subStr = strHandler("无与伦比,为杰沉沦", (str)->str.substring(5,9));
        System.out.println(subStr);
    }
    private static String strHandler(String str,Function<String,String> fun){
        return fun.apply(str);//传入一个字符串,有返回值。
    }

    //Predicate<T> 断言型接口: boolean test(T t);
    private static void test4(){
        List<String> list=Arrays.asList("Hello","jj","Lambda","www","ok");
        List<String> strList = filterStr(list, s->s.startsWith("L"));        
        List<String> list2=filterStr(list, new Predicate<String>() {
                        @Override
                        public boolean test(String t) {
                                // TODO 自动生成的方法存根
                                return t.length()>3;//((String)t).length()>3;
                        }
                });        
        for (String string : strList) {
            System.out.println(string);
        }
    }
    //需求:将满足条件的字符串,放入集合中
    private static List<String> filterStr(List<String> list,Predicate<String> pre){
        List<String> strList = new ArrayList<>();
        for ( String str : list) {
            if(pre.test(str)){
                strList.add(str);
            }
        }
        return strList;
    }
}

方法引用与构造器引用

* 一、方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”(可以理解为方法引用时Lambda表达式的另一种表现形式)

* 主要有三种语法格式:

* 对象::实例方法名

* 类::静态方法名

* 类::实例方法名

* 注意:

* 1、Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!

* 2、若Lambda参数列表中的第一个参数是 实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method

* 二、构造器引用:

* 格式:

*ClassName::new

* 注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致!

* 三:数组引用:

String[]::new

Employee.java

1.代码实现

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

public class TestMethodRef { 

        public static void main(String[] args){
                test6();
        }

    //1)对象::实例方法名
    private static void test1(){
        //PrintStream ps1 = System.out;
        //Consumer<String> con = (x)->System.out.println(x);  //生成了一个实现了Consumer接口的类的对象,accept()方法,消费型接口,一个参数,没有返回值
        Consumer<String> con = System.out::println;
        con.accept("Hello.....");
        
        //实现out的类是PrintStream类        
//        PrintStream ps = System.out;
//        Consumer<String> con1 = ps::println;       //相当于上面,引用了ps对象的println()方法
//        Consumer<String> con2 = System.out::println;
//        con2.accept("abcdef");
    }
    private static void test2(){
        final Employee emp = new Employee();
        //Supplier<String> sup = ()->emp.getName();                    //供给型接口,get()方法,没有参数,一个返回值
        Supplier<String> sup = emp::getName;
        String str = sup.get();
        System.out.println(str);
        
        Supplier<Integer> sup2 = emp::getAge;
        Integer num=sup2.get();
        System.out.println(num);
    }

    //2)类::静态方法名
    private static void test3(){
        //comparator实现接口的方法是compare方法。比较接口。
        
        //Comparator<Integer> com = (x,y)->Integer.compare(x,y);       
        Comparator<Integer> com1 = Integer::compare;
        System.out.println(com1.compare(33, 33));
    }

    //3)类::实例方法名
    private static void test4(){
        
        //BiPredicate待两个参数,一个返回值
        //BiPredicate<String,String> bp = (x,y)->x.equals(y); //String::equals
        BiPredicate<String, String> bp2 = String::equals;
        System.out.println(bp2.test("Hell", "Hell"));
        
    }

    //构造器引用
    public static void test5(){
        //Supplier<Employee> sup = ()->new Employee();
        //构造器引用方式
//        Supplier<Employee> sup2=Employee::new;//使用无参构造器
//        Employee emp = sup2.get();
//        System.out.println(emp);

        //Function含有一个参数和一个返回值,
        //Function<Integer,Employee> fun2 = (x)->new Employee(x);
        Function<Integer,Employee> fun2 = Employee::new;
        Employee emp2 = fun2.apply(101);
        System.out.println(emp2);

        BiFunction<String,Integer,Employee> bf = (x, y) -> new Employee(x, y);
        //BiFunction<String,Integer,Employee> bf = Employee::new;
        Employee e = bf.apply("Tom", 22);
        System.out.println(e);
    }

    //数组引用
    private static void test6(){
        //使用Function返回长度为第一个参数的数组
        //Function<Integer,String[]> fun = (x)->new String[x];
        Function<Integer,String[]> fun = String[]::new;
        String[] strs = fun.apply(10);
        System.out.println(strs.length);

        Function<Integer,String[]> fun2 = String[]::new;
        String[] str2 = fun2.apply(20);
        System.out.println(str2.length);
    }
}

2.employee.java

public class Employee {
    
    private String firstName;
    private String lastName;
    private double salary;
    private String department;


        private int age;

    public Employee(){
        System.out.println("Employee() is called.");
    }
    
    public Employee(int age){
        this.age = age;
    }
    
    public Employee(String firstName, int age){
        this.firstName = firstName;
        this.age = age;
    }
    
    public Employee(String firstName, int age, double salary){
        this.firstName = firstName;
        this.age = age;
        this.salary = salary;
    }
    
    public Employee(String firstName, String lastName, double salary, String department) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.salary = salary;
    this.department = department;
    }

    public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }
        
    // set firstName
    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }

    // get firstName
    public String getFirstName() {
    return firstName;
    }

    // set lastName
    public void setLastName(String lastName) {
    this.lastName = lastName;
    }

    // get lastName
    public String getLastName() {
    return lastName;
    }

    // set salary
    public void setSalary(double salary) {
    this.salary = salary;
    }

    // get salary
    public double getSalary() {
    return salary;
    }

    // set department
    public void setDepartment(String department) {
        this.department = department;
    }

    // get department
    public String getDepartment() {
        return department;
    }

    // return Employee's first and last name combined
    public String getName() {
        return String.format("%s %s", getFirstName(), getLastName());
    }

    @Override
    public String toString() {
        return String.format("%-8s %-8s %d %8.2f %s", getFirstName(), getLastName(), age, getSalary(), getDepartment());
    } 
}