Lambda表达式

Lambda基本语法

Java8中引入了新的操作符” - >“符号,称为箭头操作符,它将表达式拆分为两部分

左侧:lambda表达式参数列表

右侧:lambda表达式所执行的功能,执行体

适用于函数式接口(下面介绍)

语法格式一:无参数,无返回值

      () -> System.out.printIn("hello");

比如:Runnable接口中的run方法

    @Test
    public void test() {
        new Thread(() -> {for (int i = 0; i < 20; i++)
        {
            System.out.println("我在跑"+i);
        }
        }).start();
    }

语法格式二:有一个参数,无返回值

 (x)->  System.out.printIn(x);

    @Test
    public void test() {
        Consumer<String > consumer = (x) -> System.out.println(x);
        consumer.accept("我的大哥");
    }

语法格式三:如果只有一个参数,小括号可以省略不写

x ->  System.out.printIn(x);

语法格式四:有两个以上的参数,并且lambda体中有多条语句,有返回值

(x,y)-> {  语句  }

    @Test
    public void test() {
        Comparator<Integer> comparator = (x,y)->{
            return Integer.compare(x,y);
        };

        System.out.println(comparator.compare(30, 20));
    }

语法格式五:Lambda表达式中的参数列表的数据类型可以省略不写

因为JVM编译器可以通过上下文推断出数据类型,即”类型推断“

比如 String[] strs = {"aaa","bbb","ccc"} , 

ArrayList<String> objects = new ArrayList<>();

拆开写就不行String strs;  strs = {"a","b"};

但是如果一个参数写上类型其余的参数也要写。

练习

一、对于学生信息进行排序,按年龄排序,如果年龄相同按学号排序

/**
 * @author wy
 */
@Data
public class Student {
    private String name;
    private int age;
    private int sno;

    public Student(String name, Integer age, Integer sno) {
        this.name = name;
        this.age = age;
        this.sno = sno;
    }
}
    @Test
    public void test1(){
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("张三1",40,1));
        students.add(new Student("张三2",20,2));
        students.add(new Student("张三3",30,3));
        students.add(new Student("张三4",40,4));
        Collections.sort(students,(e1,e2)->{
            if (e1.getAge()==e2.getAge()){
                return Integer.compare(e1.getSno(),e2.getSno());
            }else {
                return Integer.compare(e1.getAge(),e2.getAge());
            }
        });
        students.stream().forEach(System.out::println);
    }

二、完成对字符串的特定操作

如将字符串转化为大写

/**
 * @author wy
 */
@FunctionalInterface
public interface MyFun<T> {
    public T getValue(T t);
}
    @Test
    public void test2(){
        System.out.println(strHandler("hello", String::toUpperCase));
    }

    public String strHandler(String str,MyFun<String> myFun){
        return myFun.getValue(str);
    }

函数式接口

什么时函数式接口

接口中只有一个抽象方法时,这个接口就是函数式接口。

函数时接口可以使用注解 @FunctionalInterface修饰,可以检查接口是不是函数式接口

内置函数式接口

像上面的操作,我们需要创建一个函数式接口去支持

java为我们提供了一些函数式接口供我们使用

Consumer<T> : 消费型接口

方法:void accept(T t);

    @Test
    public void test4(){
        happy(1000.00,(x)-> System.out.println("我洗了"+x+"元的澡,就是消费,我开心"));
    }

    public void happy(Double money,Consumer<Double> consumer){
            consumer.accept(money);
    }

Supplier<T>:供给型接口

方法:T get();

需求:产生指定个数整数,放入集合中

    @Test
    public void test5(){
        getNumList(5,()->(int)(Math.random()*100)).forEach(System.out::println);
    }

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

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

方法:R apply(T t);

需求:处理字符串 转化为大写

    @Test
    public void test9(){
        System.out.println(strHandler2("abc", (x)->x.toUpperCase()));
    }

    public String strHandler2(String str, Function<String,String> function){
            return function.apply(str);
    }

Predicate<T >;断言型接口

方法:boolean test(T t);

需求:将满足条件字符串添加到集合中去

    public void test8(){
        List<String> list = Arrays.asList("Hello","nihao","lambda","ok");
        System.out.println(filterStr(list, (s) -> s.length() > 3));
    }

    public List<String> filterStr(List<String> strings, Predicate<String> predicate){
        ArrayList<String> strings1 = new ArrayList<>();
        for (String s: strings) {
            if (predicate.test(s)){
                strings1.add(s);
            }
        }
        return strings1;
    }

方法引用

方法引用:

若lambda表达式体中的内容有方法已经实现了,我们可以使用“方法引用”

注意:

1、lambda方法体中方法的参数列表和返回值,要与函数式接口中的抽象方法的参数列表和返回值相同

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

语法格式:

对象::实例方法名

    @Test
    public void test11() {
        Consumer<String> consumer = (s -> System.out.println(s));
        //lambda体中的方法已经实现了改功能
        //接口中的参数列表和返回值要与方法中的参数列表和返回值相同
        PrintStream out = System.out;
        Consumer<String> consumer1 = out::println;

        Consumer<String > consumer2 = System.out::println;
        consumer2.accept("abc");
    }
    @Test
    public void test12(){
        //供给性接口返回学生的名字
        Student student = new Student();
        Supplier<String> stringSupplier = ()-> student.getName();
        System.out.println(stringSupplier.get());

        Supplier<String> stringSupplier1 = student::getName;
    }

类::静态方法名

    @Test
    public void test13(){
        Comparator<Integer> comparator = (x,y)->Integer.compare(x,y);
        Comparator<Integer> comparator1= Integer::compare;
    }

类::实例方法名

    @Test
    public void test14(){
        //比较两个字符串是不是一样
        BiPredicate<String,String> bp = (x,y)->x.equals(y);
        BiPredicate<String,String> bp1 = String::equals;
    }

构造器引用

格式:

构造器::方法

第一个Student::new使用的是无参构造器

第二个Student::new使用的是有一个参数的构造器

    @Test
    public void test15(){
        Supplier<Student> studentSupplier = ()->new Student();
        Student student = studentSupplier.get();
        //构造器引用
        Supplier<Student> studentSupplier1 = Student::new;

        Function<String,Student> function = Student::new;
        Student student1 = function.apply("www");
        System.out.println(student1.getName());
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值