zoukankan      html  css  js  c++  java
  • java8(1)--- lambda

    项目马上切java8了,之前对于java8的东西都是东打一棒西打一锤的了解了些。这次搜集整理了下,从lambda到stream相关的API等。

    1.Lambda和匿名内部类

    Lambda 是一个匿名的函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递),我一直都认为它就是匿名内部类的变种进化。

    匿名内部类:

    //匿名内部类
    Runnable runnable1 = new Runnable() {
            @Override
             public void run() {
                System.out.println("匿名内部类");
            }
     };

     Lambda表达式:

    //lambda表达式
     Runnable runnable2 = () -> System.out.println("lambda");

    2.Lambda语法:

    Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “->”,将表达式分成两部分,左边是参数体,右边是Lambda体,需要函数式接口(接口中只有一个抽象方法的接口,称为函数式接口) 的支持,可以使用注解 @FunctionalInterface 修饰

    几种语法格式:

     其中:

      只有一个参数,可以省略小括号

      Lambda体只有一条语句可以省略{}

      参数类型可以省略,编译器可以通过上下文推断参数类型

            //无参无返回/大括号省略
            Runnable runnable3 = () -> System.out.println("lambda");
    
            //有参无返回/小括号省略
            Consumer<String> consumer = (args) -> System.out.println(args);
            Consumer<String> consumer2 = args -> System.out.println(args);
    
            //有参有返回值/参数类型省略
            Function<Integer, Integer> function = x -> x + 1;
            Function<Integer, Integer> function1 = (Integer x) -> x + 1;
            //lambda体内正常逻辑操作
            Function<Integer, Integer> function3 = (Integer x) -> {
                if(x < 100) {
                    return x;
                }
                return x + 1;
            };

    3. java8 内置函数式接口(java.util.function包)

    主要分为四种类型(主要就是对应几种方法类型,有参无返回,无参有返回,有参有返回)
    Consumer<T> : 消费型接口
    void accept(T t);

    Supplier<T> : 供应型接口
    T get();

    Function<T, R> : 功能型接口
    R apply(T t);

    Predicate<T> : 断言型接口
    boolean test(T t);

    其他的几乎都是在这四种类型上面进行的扩展,比如 DoubleConsumer 指定了参数类型是double,void accept(double value); ,而Consumer的参数类型是泛型 void accept(T t);,再比如BiFunction和Function相比就是入参变成了两个R apply(T t);R apply(T t, U u);

    4.Lambda语法的另外一种形式 --- 方法引用

    若 Lambda 体中的功能,已经有方法提供了实现,可以使用方法引用,前提是接口抽象方法的参数和已经有方法的参数一致,表现形式如下:

         1. 对象实例::实例方法名

         2. 类名::静态方法名

         3. 类名::实例方法名

    注意: 第三种表现形式需要Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式:ClassName::MethodName

            Student student = new Student(101, "张三", 18, 95);
    
            Supplier<String> sup = () -> student.getName();
            System.out.println(sup.get());
            //对象实例::实例方法名 同上
            sup = student::getName;
            System.out.println(sup.get());
            
            Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
            //类名::静态方法名 同上
            Comparator<Integer> com1 = Integer::compare;
    
            //类名::实例方法名 第一个参数是Student实例 lambda体调用Student的show方法ClassName::MethodName
            Function<Student, String> fun = Student::show;
            System.out.println(fun.apply(student));

    5.Lambda语法的另外一种形式 --- 构造器引用

    构造器的参数列表,需要与函数式接口中方法参数列表保持一致

    表现形式:类名::new

    数组引用:函数式接口中方法参数是新数组的长度

    表现形式:类型[]::new

            //构造器引用
            Function<String, Student> fun1 = Student::new;
    
            Function<Integer, String[]> fun2 = (args) -> new String[args];
            String[] strs = fun2.apply(2);
            System.out.println(strs.length);
            //数组引用 效果同上
            Function<Integer, Student[]> fun3 = Student[]::new;
            Student[] students = fun3.apply(20);
            System.out.println(students.length);

    Student代码:

        private int id;
        private String name;
        private int age;
        private double score;
    
        public Student(String name) {
            this.name = name;
        }
    
        public Student(int id, String name, int age, double score) {
            this.id = id;
            this.name = name;
            this.age = age;
            this.score = score;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        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;
        }
    
        public double getScore() {
            return score;
        }
    
        public void setScore(double score) {
            this.score = score;
        }
    
        public String show() {
            return "测试方法引用";
        }
  • 相关阅读:
    Distinct Values
    树状数组求逆序数
    Color the ball
    Cube
    树状数组
    手动编写JQUERY插件
    JQuery和原生JS跨域加载JSON数据或HTML。
    使用CEF(CEFGLUE)作为您的客户端UI(一)
    给IIS添加网站配置权限
    SQL SERVER 报:由于数据移动,未能继续以 NOLOCK 方式扫描错误的解决办法。
  • 原文地址:https://www.cnblogs.com/nijunyang/p/11333511.html
Copyright © 2011-2022 走看看