Lambda表达式的相关学习(22.6.27)

Lambda 表达式的核心语法
Lambda 表达式在Java 语言中引入了一个新的语法元 素和操作符。这个操作符为 “->” ,
该操作符被称 为 Lambda 操作符或剪头操作符。它将 Lambda 分为 两个部分:
    左侧:指定了 Lambda 表达式需要的所有参数
    右侧:指定了 Lambda 体,即 Lambda 表达式要执行 的功能。

    Lambda表达式 需要一个 函数式接口 来支持 ,什么是函数式接口  即接口中只有一个抽象方法   使用@FunctionalInterface  注解修饰

    语法格式1  test1
     无参无返回值  参数的小括号不能省  如果大括号内 就一条语句 大括号也可以省

    语法格式2  test2
    一个参数 无返回值   参数的小括号可以省略  如果方法体就一条语句 大括号也可以省略

    语法格式3  test3
     两个以上参数 有返回值  参数的小括号不能省略  如果方法体就一条语句 大括号也可以省略


    Lambda 表达式的参数列表的 参数类型 可以省略
/**
 * @author GuoShuo
 * @date 2022/6/27 19:33
 */
public class Lambdademo1 {
    @Test
    public void test1(){
        //无参无返回值
        Runnable r1 =() -> {} ;
        Runnable r2 =() -> System.out.println("这里大括号可以省略");
        Runnable r3 =() -> {System.out.println("这里大括号可以省略");};
    }

    @Test
    public void test2(){
        //有一个参  没有返回值

        Consumer c = para -> System.out.println("昨晚花了"+para+"钱");
        Consumer c1 = para -> {
            System.out.println("今天花了"+para+"钱");
        };
        c.accept(200);
        c1.accept(300);
    }

    @Test
    public void test3(){
        //有两个以上参数,有返回值
        Comparator<Integer> con1 = (Integer num1,Integer num2) ->{return 1;};
        Comparator<Integer> con2 = (num1,num2) -> {return Integer.compare(num1,num2);};//参数的类型可以省略
        Comparator<Integer> con3 =  (num1,num2)->Integer.compare(num1,num2) ;  //省略掉了大括号和return

    }

    @Test
    public void test4(){
        Integer result = method(3,(num) ->{
            return num * num;
        });

    }

    public Integer method(Integer num,MyFunInter<Integer> inter){

        return inter.getValue(num);
    }


    List<Student> list = Arrays.asList(
            new Student(1,"zs",18,88.5),
            new Student(2,"ls",14,89.5),
            new Student(3,"ww",21,86.5),
            new Student(4,"zl",19,98.5),
            new Student(5,"tq",22,82.5),
            new Student(6,"mb",21,83.5)
    );

    @Test
    public void test5(){
        // 使用断言型接口  过滤集合   得到90 分以上的学生信息
        List<Student> students = method2(list, (s) -> {
            return s.getScore() > 90;
        });

        System.out.println(students);
    }

    public List<Student> method2(List<Student> list, Predicate<Student> pre){
        List<Student> students = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            if(pre.test(list.get(i))){
                students.add(list.get(i));
            }
        }

        return students;
    }

}
@FunctionalInterface
public interface MyFunInter<T> {

    public T getValue(T t);
}

---------------------------------------------------------------------------------------------------------------------------------

相关练习
1. 调用Collections.sort() 方法  通过定制排序  比较Student  先按照年龄比  年龄相同再按照成绩比  升序
2. 声明函数式接口   接口中声明抽象方法   public String getValue(String str)
   再定义一个方法   使用这个接口作为参数 实现 将一个字符串 转大写 并返回
                                     实现 讲一个字符串 截取2到4 的索引位置

3. 声明一个带泛型的函数式接口   泛型类型为<T,R>  T 为参数  R 为返回值
                                     实现  计算两个Long类型的数的和
/**
 * @author GuoShuo
 * @date 2022/6/27 21:16
 */
public class LambdaDemo2 {

    List<Student> list = Arrays.asList(
            new Student(1,"zs",18,88.5),
            new Student(2,"ls",14,89.5),
            new Student(3,"ww",21,86.5),
            new Student(4,"zl",19,98.5),
            new Student(5,"tq",22,82.5),
            new Student(6,"mb",21,83.5)
    );

    @Test
    public void test1(){
        Collections.sort(list,(s1,s2) ->{
            if (s1.getAge()>s2.getAge()){
                return 1;
            }else if (s1.getAge()==s2.getAge()){
                return s1.getScore().compareTo(s2.getScore());
            }else {
                return -1;
            }
        });
        System.out.println(list);
    }

    @Test
    public void test2(){
        String hello = method2("hello",(s) ->{
            return s.toUpperCase();//转为大写
        });

        String helloworld =method2("helloworld",(s) ->{
            return s.substring(2,4);
        });

    }

    public String method2(String str,MyFunInter1 myFunInter1){
        return myFunInter1.getValue(str);
    }


    @Test
    public void test3(){
        Long along = method3(3L,5L,(num1,num2) ->{
            return num1+num2;
        });

    }

    public Long method3(Long num1,Long num2,MyFunInter2<Long,Long> myFunInter2){
        return myFunInter2.testFun(num1,num2);
    }

}
public interface MyFunInter1 {

    public String getValue(String str);
}
public interface MyFunInter2<T,R> {

    public R testFun(T t1,T t2);
}
---------------------------------------------------------------------------------------
内置的函数式接口的练习

Consumer<T>  消费型接口     参数类型为T   返回值为  void

Supplier<T>  供给型接口     无参有返回值     T get();

Function<T,R>  函数型接口    参数类型为T  返回值类型为R

Predicate<T>  断言型接口     参数类型为T  返回值类型 boolean
/**
 * @author GuoShuo
 * @date 2022/6/27 21:43
 */
public class LambdaDemo3 {
    @Test
    public void test1(){
        //消费型接口的使用
        method1(200.0,(para)->{
            System.out.println("花了钱"+para+"去学习Java");
        });
    }

    public void method1(Double money, Consumer<Double> con){
        con.accept(money);
    }

    @Test
    public void test2(){
        // 供给型接口
        // 需求 得到n 个 1000 以内的随机数
        List<Integer> list =method2(10,() ->{
            return new Random().nextInt(1000);
        });
        System.out.println(list);

    }

    public List<Integer> method2(Integer n, Supplier<Integer> supplier){
        List<Integer> integers =new ArrayList<>();
        for (int i = 0; i < n; i++) {
            Integer number = supplier.get();
            integers.add(number);
        }
        return integers;
    }

    @Test
    public void test3(){
        //函数型接口
        Student student = new Student();
        student.setName("张三");
        String s1 =method3(student,(s) ->{
            return s.getName()+"好好学习";
        });
        System.out.println(s1);
    }

    public String method3(Student student, Function<Student,String> function){
        return function.apply(student);
    }

    @Test
    public void test4(){
        List<String> list = Arrays.asList("java", "javaee", "mybatis", "springboot");
        List<String> list1 =method4(list,(s) ->{
           return s.length()>5;
        });

        System.out.println(list1);

    }

    public List<String> method4(List<String> list, Predicate<String> predicate){
        List<String> strings = new ArrayList<>();
        list.forEach((s)->{
            if(predicate.test(s)){
                strings.add(s);
            }
        });

        return strings;
    }
}
---------------------------------------------------------------------------------------
方法引用
实现抽象方法的参数列表    必须 与 方法引用的参数列表 保持一致
//list.forEach((s)->{System.out.println(s);});
//方法引用的形式
list.forEach(System.out::println);

 方法引用的语法格式:
 对象名::实例方法名
 类名::静态方法名
 类名::实例方法名

 什么时候使用方法引用呢?

 当函数式接口的抽象方法的参数列表  与  lambda 体中的 所引用的 方法的参数列表 一致时(参数的类型        个数 顺序)  可以使用方法引用
 只要参数列表一致  就可以使用方法引用
/**
 * @author GuoShuo
 * @date 2022/6/27 21:44
 */
public class TestMethodRef {
    List<Student> list = Arrays.asList(
            new Student(1,"zs",18,88.5),
            new Student(2,"ls",14,89.5),
            new Student(3,"ww",21,86.5),
            new Student(4,"zl",19,98.5),
            new Student(5,"tq",22,82.5),
            new Student(6,"mb",21,83.5)
    );

    @Test
    public void test1(){
        list.forEach((s) ->{
            System.out.println(s);
        });
        //方法引用的形式
        list.forEach(System.out::println);
    }

    @Test
    public void test2(){
        //Consumer<String> consumer = (s) -> s.substring(2);
        //
        //Consumer<Integer> consumer2 = "hello"::substring;  // 参数列表  指的是 参数的类型 顺序 个数
        //
        //consumer2.accept(2);

        Student stu = new Student(1,"zs",18,88.8);
        Consumer<String> con =(s) ->stu.myMethod1(s);
        //变形为方法引用
        Consumer<String> con2 = stu::setName;

    }

    @Test
    public void test3(){
        Student student = new Student(1,"zs",18,99.9);
        Supplier<Integer> supplier = () -> student.getAge();
        //引用形式
        Supplier<Integer> supplier2 = student::getAge;
    }

    @Test
    public void test4(){
        //类名::静态方法名
        Comparator<Integer> comparator = (x,y) -> {return Integer.compare(x,y);};
        Comparator<Integer> comparator1 = Integer::compare;
        Comparator<Integer> comparator2 = Integer::compare;
    }


    @Test
    public void test5(){
        //类名::实例方法名
        Function<Student,String> function = (s) -> {return s.getName();};
        Function<Student,String> function1 = Student::getName;

        BiPredicate<String,String> bi = (s1,s2) -> {return s1.equals(s2);};
        BiPredicate<String,String> bi2 = String::equals;

        //什么情况下可以这样写?
        //当第一个参数 是方法的调用者, 第二个 及 以后的参数 是方法的参数时  可以  类名::实例方法名

    }
}
/**
 * @author GuoShuo
 * @date 2022/6/28 12:01
 * 数组引用
 */
public class TestArrayRef {
    @Test
    public void test(){
        Function<Integer,String[]> function =(length) -> new String[length];
        Function<Integer,String []> function1 = String[]::new;

    }
}
/**
 * @author GuoShuo
 * @date 2022/6/28 12:21
 * 
 * 构造器引用
 */
public class TestConstructorRef {
    @Test
    public void test1(){
        //构造器引用
        Supplier<Student> supplier = () -> new Student();
        Supplier<Student> supplier1 = Student::new;

        Student student = supplier1.get();
    }


    @Test
    public void test2(){
        //构造器引用的增强练习
        Consumer<Integer> consumer = (age) -> new Student(age); //调用参数为年龄的构造方法
        Consumer<Integer> consumer1 = Student::new;             //和Consumer的抽象方法的参数列表一致  所以可以这样写
        consumer1.accept(18);


        Function<Integer,Student> function =(age) -> new Student(age);
        Function<Integer,Student> function1 = Student::new;
        Student result =function1.apply(20);

        BiFunction<String,Integer,Student> biFunction = (name,age) -> new Student(name,age);
        BiFunction<String,Integer,Student> biFunction1 = Student::new;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值