lambda表达式

lambda简介

lambda表达式是java8中的一个重要的特性,允许通过表达式来代替功能接口。lambda和方法一样,提供了一个正常的参数列表和一个使用这些参数的主体,主体可以是一个表达式或一个代码块。lambda可以看做是一个匿名内部类的语法糖,也可以称为闭包。

优点:

  • 代码简洁,开发迅速
  • 方便函数式编程
  • 过滤和计算非常容易
  • 改善了集合类的操作

缺点:

  • 代码可读性差
  • 不容易进行调试
  • 在非并行计算中,一些计算未必有传统的for循环性能高

语法

(parameters)-> expression 表达式

(parameters)->{statements;} 语句块

由三个部分组成:

  • parameters:类似方法中的形参列表,这里的参数是接口里的参数,可以明确声明,也可以不声明,类型由jvm推断

  • -> 可翻译为被用于的意思

  • 方法体:可以是表达式,也可以是代码块。代码块可以返回一个值,也可以不返回一个值,此处代码块相当于接口的实现的方法体

请添加图片描述

函数式接口

定义:一个接口中有且只有一个抽象方法

注解校验接口是否是函数式接口

请添加图片描述

public class Test {
    public static void main(String[] args) {
        //无参 无返回值,只有一行语句
        MyInter inter = () -> System.out.println("hello");

        //无参,无返回值,有多行语句
        MyInter1 inter1 = () -> {
            System.out.println("hello");
            System.out.println("hello");
        };

        //有一个参数没有返回值,只有一行语句
//        MyInter2<String>  inter2 = (String x) ->{
//            System.out.println(x);
//        };
        MyInter2<String>  inter2 = x->System.out.println(x);
//        MyInter2<String>  inter2 = System.out::println;

        //有一个参数,有返回值,只有一行语句:右侧大括号和return可省略
        MyInter3<Integer>  inter3 = x -> Math.abs(x);

        //有两个或以上参数,有返回值
        MyInter4 inter4 = (x,y) -> (int) Math.pow(x,y);
        MyInter4 inter41 = (x,y) -> {
            int sum =1;
            for (int i = 0; i <= y; i++) {
                sum *=x;
            }
            return sum;
        };

    }
}



interface  MyInter {
    void test();
}

interface  MyInter1 {
    void test();
}

interface  MyInter2 <T>{
    void test(T t);
}

interface  MyInter3 <T>{
    Integer abs(T t);
}


interface  MyInter4 {
    int pow(int x,int y);
}

四个核心函数式接口

接口名类型抽象方法
Consumer消费型接口void accept(T t);
Supplier供给型接口T get();
Function<T,R>函数型接口R apply(T t);
Predicate断言型接口boolean test( T t);

其他函数式接口

请添加图片描述

  1. Consumer

    public static void main(String[] args) {
       demo();
    }
    public  static  void  demo(){
        //接收一个参数,没有返回值
        Consumer  consumer = (X) -> System.out.println("hello");
        consumer.accept(12);
    }
    
  2. Supplier

    可以生产一个需要的数据,又不需要提供参数,就可以使用供给型接口

       public static void main(String[] args) {
    
            Supplier<String>  supplier = () -> {
                Random random = new Random();
                String code= "";
                for (int i = 0; i < 4; i++) {
                    int x = random.nextInt(10);
                    code += x;
                }
                return  code;
            };
            List<String>  codelist = getCode(10,supplier);
            System.out.println(codelist);
        }
        /**
         * 获取代码
         *
         * @param x        生成几个随机数验证码
         * @param supplier 供应商
         * @return {@link List}<{@link String}>
         */
        public  static List<String> getCode(int x, Supplier<String> supplier){
            List<String> list = new ArrayList<>(x);
            for (int i = 0; i < x; i++) {
                list.add(supplier.get());//get()可以返回任意类型
            }
            return list;
        }
    }
    
  3. Function

    需要在一个方法中。传入参数,获取一个返回值,可以使用函数型接口

      public static void main(String[] args) {
    //        Function<Double, Double> function = (x) -> {
    //            return (int) (x * 100 + 0.5) / 100D;
    //        };
    
            Function<Double,Double> function = x -> (int) (x * 100 + 0.5) / 100D;//保留两位小数操作
            System.out.println(k2(3.1415, function));
        }
    
        public static double k2(double i, Function<Double, Double> function) {
            return function.apply(i);
    
        }
    
  4. Predicate

    在方法中传一个参数,方法进行判断,返回boolean类型的值,需要使用断言型接口

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("123");
        list.add("143");
        list.add("123");
        list.add("133");
        list.add("123");
        Predicate<String>  predicate = x -> x.equals("123");
        List<String> filter = filter(list, predicate);
        for (String s : filter) {
            System.out.println(s);
        }
    
    }
    
    
    public  static List<String>  filter(List<String> list, Predicate<String> predicate){
        List<String> list1 = new ArrayList<>();
        for (String s : list) {
            boolean test = predicate.test(s);
            if (test){
                list1.add(s);
            }
        }
        return list1;
    }
    

方法引用

如果lambda表达式体中的功能 有方法已经实现了,则可以使用方法引用

lambda表达式体中调用方法的参数列表和返回值,要和函数式接口中定义的抽象方法参数列表和返 回值一致。

语法格式:
静态方法引用: 类名:: 静态方法名

实例方法引用: 实例对象名:: 实例方法名

特殊方法引用: 类名:: 实例方法名

构造方法引用: 类名:: new

  1. 静态方法引用

        public static void main(String[] args) {
            List<Integer> list = Arrays.asList(12,32,15,6,78,25);
    //        list.sort(new Comparator<Integer>() {
    //            @Override
    //            public int compare(Integer o1, Integer o2) {
    //                return Integer.compare(o1,o2);
    //            }
    //        });
    //        list.sort(( o1,  o2)-> Integer.compare(o1,o2));
    //        System.out.println(list);
            //静态方法引用
            list.sort(Integer::compare);
            System.out.println(list);
        }
    
  2. 实例方法引用

    public class Test {
        public static void main(String[] args) {
            /*List<Integer> list= Arrays.asList(12,32,15,6,78,25);
            //list.sort((o1, o2)->Integer.compare(o1,o2));
            list.sort(Integer::compare);
            System.out.println(list);*/
            // Consumer<String> consumer=X::test;
            //X x = new X();
            //Supplier<Integer> supplier = new X()::random;
            List<Integer> list= Arrays.asList(12,32,15,6,78,25);
            list.forEach(System.out::println);
        }
    }
    
    class X {
        public static void test(String x) {
        	System.out.println(x);
        }
        public int random() {
        	Random r = new Random();
            return r.nextInt(10);
        }
    
    }
    
  3. 特殊方法引用

    public class Test1 {
        public static void main(String[] args) {
            //当我们函数中有参数,第一个参数来调用方法,可以使用特殊方法引用
            /* String s="abc";
            Function<String,String> f=String::toUpperCase;
            System.out.println(f.apply(s));*/
            BiPredicate<String, String> predicate = String::equals;
            System.out.println(predicate.test("abc","abc"));
            }
    }
    
  4. 构造方法引用

    调用的构造方法的参数列表和函数式接口中抽象方法的参数列表一致

    public class Test2 {
        public static void main(String[] args) {
            // Supplier<Teacher> supplier=Teacher::new;
            // System.out.println(supplier.get());
            /* Function<String,Teacher> function=Teacher::new;
            System.out.println(function.apply("李白"));*/
            BiFunction<String,Integer,Teacher> function=Teacher::new;
            System.out.println(function.apply("李白",20));
        }
    }
    class Teacher{
        private String name;
        private Integer age;
        public Teacher() {
        	System.out.println("无参构造方法");
        }
        public Teacher(String name){
            this.name=name;
            System.out.println("有一个参数的构造方法");
        }
        public Teacher(String name, Integer age) {
            this.name = name;
            this.age = age;
            System.out.println("有两个参数的构造方法");
        }
        @Override
        public String toString() {
            return "Teacher{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
        }
    }
    
  5. 数组引用

    数组类型[]::new

    public class Test3 {
        public static void main(String[] args) {
            // Function<Integer,Integer[]> function=x->new Integer[x];
            Function<Integer,Integer[]> function= Integer[]::new;
            Integer[] apply = function.apply(10);
            Arrays.fill(apply,10);
            System.out.println(Arrays.toString(apply));
            System.out.println(apply.length);
        }
    }
    
  6. this 和 super引用方式

    class XX{
        public void test1(String str){
        }
        public void test2(String str){
            //Consumer<String> consumer=s->test1(s);
            Consumer<String> consumer=this::test1;
        }
    }
    
    
    class YY extends XX{
        public void test(String str){
       		 //Consumer<String> consumer=s->test1(s);
        	 Consumer<String> consumer=super::test1;
        }
    }
    
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小郑在努力ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值