Lambda表达式

Lambda表达式

Lambda表达式是一个匿名函数,匿名内部对象,根据面向对象的特征了解到,接口是不可以被实例化的,但是可以通过其继承该接口的子类来创建父类对象,即该接口对象,由于接口是全抽象的,所以子类对于父类的方法必须重写,在这里Lambda表达式应用就使用了此原理,使之得到接口对象;

public class Test01 {
    public static void main(String[] args) {
        //在这里new A(){}实际上创建接口A的子类对象,由于会自动向上转型,所以得到了父类对象,即A的对象a
       A a=new	 A(){
           //重写sum方法
            @Override
            public int sum(int a, int b) {
                int sum=a+b;
                System.out.println("两数之和为:"+sum);
                return sum;
            }
           //重写pow1方法
            @Override
            public double pow1(int a,int b){
                double p=Math.pow(a,b);
                System.out.println(p);
                return p;
            }
        };
       a.sum(1,2);
       a.pow1(1,3);
    }

}
interface A{
    int sum(int a,int b);    //定义一个求和的方法
    double pow1(int a,int b); //定义一个求a^b的方法
}

Lambda表达式的使用条件

  • Lambda表达式的使用需要函数式接口的支持。

函数式接口:接口种有且仅有一个抽象方法的接口,称为函数式接口。

Lambda的使用用例二--------无参数,无返回值情况

package com.ysh.demo.review03;
/**
 * 需求:利用Lambda表达式打印Helloword,并且传入一个String类型的参数
 */
public class DemoLambdaTest01 {
    public static void main(String[] args) {
        /**
         * 方法一
         */
        RandomTest rt=new RandomTest() {
            //重写rdt方法
            @Override
            public void rdt() {
                System.out.println("HelloWorld  ");
            }
        };
        rt.rdt();  //调用重写后的方法,在这里发生了多态现象
        /**
         * 方法二
         * Lambda写法思路:{}可以省略
         */
        RandomTest rt2=()->{
            System.out.println("HelloWorld  ");
        };
        rt2.rdt();
    }

}
interface RandomTest{
    void rdt();
}

Lambda的使用用例一-------有参数,无返回值情况

package com.ysh.demo.review03;
/**
 * 需求:利用Lambda表达式打印Helloword,并且传入一个String类型的参数追加到HelloWord末尾
 */
public class DemoLambdaTest01 {
    public static void main(String[] args) {
        /**
         * 方法一
         */
        RandomTest rt=new RandomTest() {
            //重写rdt方法
            @Override
            public void rdt(String s) {
                System.out.println("HelloWorld  "+s);
            }
        };
        rt.rdt("yang");  //调用重写后的方法,在这里发生了多态现象
        /**
         * 方法二
         * Lambda写法思路:(String s) 表接口中方法签名其中的String可以省略
         */
        RandomTest rt2=(String s)->{
            System.out.println("HelloWorld  "+ s);
        };
        rt2.rdt("yang");
    }
   
}
interface RandomTest{
    void rdt(String s);
}

Lambda使用用例三----有参数有返回值情况

package com.ysh.demo.review03;
/**
 * 需求:利用Lambda表达式打印Helloword,并且传入一个String类型的参数追加到HelloWord末尾
 */
public class DemoLambdaTest01 {
    public static void main(String[] args) {
        /**
         * 方法一
         */
        RandomTest rt=new RandomTest() {
            //重写rdt方法
            @Override
            public int rdt(String s) {
                System.out.println("HelloWorld  "+s);
                return 1;
            }
        };
        rt.rdt("yang");  //调用重写后的方法,在这里发生了多态现象
        /**
         * 方法二
         * 
         */
        RandomTest rt2=(String s)->{
            System.out.println("HelloWorld  "+ s);  
            return 1;
        };
        rt2.rdt("yang");
    }

}
interface RandomTest{
    int rdt(String s);
}

Lambda使用用例四------有返回值无参数情况

package com.ysh.demo.review03;
/**
 * 需求:利用Lambda表达式打印Helloword,并且传入一个String类型的参数
 */
public class DemoLambdaTest01 {
    public static void main(String[] args) {
        /**
         * 方法一
         */
        RandomTest rt=new RandomTest() {
            //重写rdt方法
            @Override
            public String rdt() {
                return "Helloworld";
            }
        };
        rt.rdt();  //调用重写后的方法,在这里发生了多态现象
        /**
         * 方法二
         * 
         */
        RandomTest rt2=()->{
            return "HelloWorld";
        };
        //以下调用效果跟上面调用效果一样
        RandomTest rt3=()-> "HelloWorld";
        
        rt2.rdt();
    }

}
interface RandomTest{
    String rdt();
}

四大内置接口消费型接口(Comsumer)、供给型接口(Supplier)、函数型接口(Function<T,R>)、断定性接口(Predictae)

消费型接口的基本使用(底层有个accept(T t)方法)

package com.ysh.demo.review03;
import java.util.Arrays;
import java.util.Collection;
public class DemoLambdaTes02 {
    public static void main(String[] args) {
        Collection<String> list= Arrays.asList("aaaa","bbbb","cccc","dddd");
        //由于forEach(Consumer<? super T> action)中的参数类型是Consumer类型,但是Consumer是个接口,所有要得到父类对象必须通过实例化子类对象,即有个类继承与Consumer
        list.forEach(s-> System.out.println(s));//s-> System.out.println(s)这个意思就是相当于与创建了一个继承Consumer接口的子类对象,但是通过自动向上继承,可以实例化父类接口对象
    }
}

供给型接口的基本使用(底层有个T get()方法)

package com.ysh.demo.review03;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.function.Supplier;

/**
 *  需求:产生指定个数的整数,整数范围为并放入集合中
 */
public class DemoLambdaTest02 {
    public static void main(String[] args) {
        //()->(int)(Math.random()*100+1)表示重写底层方法T get()
        List<Integer> numList=getNumList(10,()->(int)(Math.random()*100+1));
    }
    //实际上以上写法相当于以下写法
    List<Integer> numList02=getNumList(10,()->{
        int a=(int)(Math.random()*100+1);
        return a;
        });
    public 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();  //供给型接口特有的方法
            list.add(n);
        }
        return list;
    }
}

Function<T, R>函数型接口的基本使用(底层有个R apply(T t)方法)

package com.ysh.demo.review03;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 *  需求:1、去掉字符串两端的空格
 *        2、截取字符串
 */
public class DemoLambdaTest03 {
    public static void main(String[] args) {
    //(str) -> {return str.trim();}表示重写R apply(T t)方法
        String newStr = strHandler("  shsxt   ", (str) -> {return str.trim();});
        System.out.println(newStr);
        newStr = strHandler("shsxt", (str) -> str.substring(2, 5));
        System.out.println(newStr);
    }
    public static String strHandler(String str, Function<String, String> fun) { return fun.apply(str); }
}

Predicate断言型接口(底层中有个Test(T)方法)

package com.ysh.demo.review03;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
     * 需求:将满足条件的字符串,放入集合中,并且返回一个集合
     */
public class DemoLambdaTest02 {
    public static void main(String[] args) {
        List<String> list3=Arrays.asList("aa","bbbb","cccc","dddd");
        //重写Predicate接口中的test方法
        filterStr(list3,(s)->{
            boolean b=(s.length()>3);
            return b;
        });
        filterStr(list3,(s)->(s.length()>3));  //等价于以上写法,即return和{}可以省略不写
    }

   
    public static List<String> filterStr(List<String> list, Predicate<String> pre) { 
        List<String> list1 = new ArrayList<>();
        for (String str1 : list) {   //遍历集合
            if (pre.test(str1)) {   //筛选元素,Predicate接口中有个test方法,即重写Predicate中的test方法即可设定筛选条件
                list1.add(str1);    //将符合要求的元素添加到集合中
            }
        }
        return list1;
    }
}

方法引用的4中表现形式

  • 对象::方法名
  • 类名::静态方法名
  • 类名::普通方法名
  • 类名::new(构造器引用)

对象::方法名

public static void test2(){
    Student stu=new Student("yang",18,1.34);
    /*
    方法一
     */
    Supplier<String> supplier=()->stu.getName();
    System.out.println(supplier.get());
    /*
    方法二
     */
    /*由于getName()方法在Student中已经存在,所以在这里可以Lambda表达式中的
    方法引用方式间接对Supplier中的get()方法实现重写过程,即构建Supplier类的匿名子类
     */
    Supplier<String> supplier2=stu::getName;
    System.out.println(supplier2.get());
}

类名::静态方法名

/**
     *运用方法:Lambda表达形式中的:类::静态方法名
     */
    public static void test3(){
        Comparator<Integer> cp=(t1,t2)->Integer.compare(t1,t2);
        Comparator<Integer> cp2=Integer::compare;
    }

类名::普通方法名

 /**
     * 运用方法:Lambda表达形式中的:类:普通方法名
     */
    public static void test4(){
        BiPredicate<String,String> bp=(x,y)->x.equals(y);
        BiPredicate<String,String> bp2=String::equals;
    }

类名::new(构造器引用):

public static void test5(){
        //Student stu2=new Student("yang",19,1.78);
        Supplier<Student> supplier=Student::new;
        System.out.println(supplier.get());
        Supplier<Student> supplier1=()->new Student("yang",19,1.78);
        System.out.println(supplier1.get());
        //这种调用方式只能是传入实参与Student中的属性互相对应,没有什么操作空间,只能通过不断修改传入的实参值来改变属性值
        BiFunction<String,Integer,Student> bf=Student::new;
        //两者等价
        BiFunction<String,Integer,Student> bf2=(s,b)->new Student(s,b);
        //这种方式可以在new Student(s,b)对其形参形态进行变化,例如:new Student(s+"hello",b+1),具有很强的操作空间
        System.out.println(bf2.apply("hello", 19));
        System.out.println(bf.apply("sheng", 19));

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值