lambda表达式,函数式接口,方法引用。

lambda表达式
函数式接口

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口(functional interface)

lambda表达式可以传递到函数式接口。

lambda表达式可以转换为接口。(函数式接口)

JavaAPI-java.util.function包中的函数式接口

BiFunciton<T,U,R>:描述了参数类型为T和U而且返回类型为R的函数。例如

BiFunction<String,String,Integer> comp =
    (first,second)->first.length() - second.length();

Predicate

pubilc interface Predicate<T>{
    boolean test(T t);
    //其他默认和静态方法
}

ArrayList类有一个removeIf方法,它的参数就是一个Predicate

这个接口专门用来传递lambda表达式。

例如

从一个数组列表删除所有null值:

list.removeIf(e->e==null);

Supplier<T>

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

供应者(supplier)没有参数,调用时会生成一个T类型的值。供应者用于实现懒计算。

例如

LocalDate hireDay = Objects.requireNonNullElseGet(day,
                                           ()->LocalDate.of(1970,1,1));

requireNonNullElseGet方法只在需要值时才调用供应者

例如:这个程序显示了如何对一个比较器和一个动作监听器使用lambda表达式。

public class LambdaTest {
    public static void main(String[] args) {
        String[] planets = {"zhangsan", "lisi", "wangwu", "zhaoliu", "wuqi","xiaoming"};
        System.out.println(Arrays.toString(planets));
        System.out.println("按字典顺序排序:");
        Arrays.sort(planets);
        System.out.println(Arrays.toString(planets));

        System.out.println("按字符串长度排序:");
        Arrays.sort(planets,(first,second)->first.length()-second.length());
        System.out.println(Arrays.toString(planets));

        Timer timer= new Timer(1000,event-> System.out.println("当前时间:"+new Date()));
        timer.start();

        //保持程序运行直到用户选择"OK"
        JOptionPane.showMessageDialog(null,"是否退出?");
        System.exit(0);
    }
}
方法引用

只有当lambda表达式的体只调用一个方法而不做其他操作时,才能把lambda表达式重写为方法引用。

例如:s->s.length() == 0 这里有一个方法调用。但是还有一个比较,所以这里不能使用方法引用

要用::操作符分隔方法名与对象或类名,有三种类型

1.object::instanceMethod

2.Class::instanceMethod

3.Class::staticMethod

1.第一种,方法引用等价于一个lambda表达式,其参数要传递到方法。

例如

System.out::println,对象是System.out,所有这个方法表达式等价于x->System.out.println(x)

public interface Actor{//演员
    void performance();//演出
}
public class Dancer{//跳舞
    public void dancer(){System.out.println("舞蹈家在跳舞");}
}
public class ActorTest{
    public static void main(String[] args){
        //匿名内部类
        /**Actor actor = new Actor(){
            @Override
            public void performance(){
               	new Dancer().dancer();
            }
        };*/
        
        //lambda表达式
        //Actor actor = ()->new Dancer().dancer();
        
        //方法引用       对象          方法
        Actor actor = new Dancer()::dancer;
        
        actor.performance();
    }
}
2.第二种,第一个参数会成为方法的隐式参数。

例如

String::compareToIgnoreCase等同于

(x,y)->x.compareToIgnoreCase(y)

3.第三种,所有参数都传递到静态方法

例如

Math::pow等价于(x,y)->Math.pow(x,y)

public interface ArraySorter{//数组排序接口
    void sortDesc(int [] arr);//降序
}
public class ArrayTools{//数组工具类
    public static void bubbleSort(int [] arr){
        for(int i = 0;i<arr.length;i++){//冒泡排序,完成降序
            for(int j = 0;j<arr.length-1-i;j++{
                if(arr[j]<arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}
public class ArraySorterTest{
    public static void main(String [] args){
        //要排序的数组
        int [] numberArr={"2","4","1","6","5","3"};
        
        //匿名内部类
        /**ArraySorter as = new ArraySorter(){
            @Override
            public void sortDesc(int arr){
                ArrayTools.bubbleSort(arr);
            }
        };*/
        
        //lambda表达式
        //ArraySorter as = arrays->ArrayTools.bubbleSort(arrays);
        
        //方法引用           类名          方法名
        ArraySorter as = ArrayTools::bubbleSort;
        as.sortDesc(numberArr);
        System.out.println(Arrays.toString(numberArr));
    }
}
可以在方法引用中使用this参数和super

例如 this::equals 等同于x->this.equals(x)

public interface Calculator{//计算器
    int calculate(int a,int b);
}
public class Person{
    public int calculate(int num1,int num2){
        //匿名内部类
        /**Calculator c = new Calculator(){
            @Override
            public int calculate(int a,int b){
                return Person.this.add(a,b);
            }
        }*/
        
        //lambda表达式
       // Calculator c = (a,b)->Person.this.add(a,b);
        
        //方法引用      this  方法名
        Calculator c = this::add;
        return c.calculate(num1,num2);
    }
    
    private int add(int a,int b){return a+b;}
}
public class PersonTest{
    public static void main(String[] args){
        Person p= new Person();
        int result = p.calculate(5,10);
        System.out.println(result);
    }
}

例如 super::equals 等同于x->super.equals(x)

public interface Customer{
    void communicate();//业务交流
}
public class SoftEngineer{//软件工程师
    //分析业务方法
    public void analysisBusyness(){
        System.out.println("软件工程师分析业务");
    }
}
public class JavaProgrammer extends SoftEngineer{//Java程序员继承软件工程师
    public void communicate(){//业务交流
       //匿名内部类
        /**Customer c = new Customer(){
            @Override
            public void communicate(){
                JavaProgrammer.super.analysisBusyness();
            }
        }*/
        
        //lambda表达式
        //Customer c = ()->JavaProgrammer.super.analysisBusyness();
        
        //方法引用     super  方法名
        Customer c = super::analysisBusyness;
        c.communicate();
    }
}
public class Test {
    public static void main(String[] args) {
        JavaProgrammer programmer = new JavaProgrammer();
        programmer.communicate();
    }
}
构造器引用

构造器引用与方法引用很类似,只不过方法名为new。

例如Person::new

//学生类型对象的构建器
public interface StudentBuilder {
    /**
     * 根据给定的字符串构建出一个学生对象
     * @param msg
     * @return
     */
    Student build(String msg);

}
public class Student {
    private String name;
    private int age;

    public Student(String line){
        String[] arr = line.split(",");
        this.name = arr[0];
        this.age = Integer.parseInt(arr[1]);
    }
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test {
    public static void main(String[] args) {
//        StudentBuilder builder = new StudentBuilder() {
//            @Override
//            public Student build(String msg) {
//                return new Student(msg);
//            }
//        };
//        StudentBuilder builder2 = msg-> new Student(msg);
        StudentBuilder builder3 = Student::new;
        Student stu = builder3.build("张三,20");
        System.out.println(stu.toString());

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值