乐趣区

读书笔记写给大忙人的JavaSE-9-核心技术-接口和lambda表达式

读书笔记 –《写给大忙人的 JavaSE 9 核心技术》—第 3 章

接口和 lambda 表达式

接口

它可以让你在不提供实现的情况下,指定应该做什么。(主要在设计阶段用得到)

示例代码

public interface Test1 {
    // 接口中的方法默认为 public
    public void saySomething(String something);
    // 在接口中可以定义静态方法
    // 静态方法只能由这个接口去调用,// 实现此接口的对象是不能调用的。static void sayMyName(){System.out.println("my name is Test1");
    }
    // 在接口中可以定义默认方法, 实现此接口的类可以重新
    // 默认方法结束了这种经典模式——提供一个接口和实现该接口大多数或全部方法的伴随类
    default void sayHello(){System.out.println("Hello");
    }
}

lambda

参考博文 1

参考博文 2

这个 lambda 表达式 和 JavaScript 里面的箭头函数很像

其核心是一种简写方式, 可以取代大部分的匿名内部类, 写出更优雅的 Java 代码。

 // 一行语句
 (String s1,String s2) -> s1.length() - s2.length()
 
 // 多行语句
  (String s1,String s2) ->{if(s1.length()>s2.length()){return "yes"}else{return "no"}
  }
  
 // 无参数
 () -> return "666"
 
 // 如果参数类型可以推导出来,则可以省略。// 示例见下方代码 

函数式接口

该接口只有一个抽象方法,该接口会被 @FunctionalInterface 这个注解所修饰

当你需要一个实现函数式接口的对象实例时,可以提供一个 lambda 表达式来创建。

import java.util.Arrays;
import java.util.Comparator;

public class Test3 {public int[] sort(int[] s) {//Arrays.sort(s);
        Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
        Comparator myComparator = new MyComparator();
        // 自动装包机制不能应用于数组。// 这里 Comparator<Integer>,是 Integer,而数组是 int 类型。这两个不一样!// 要把 int 改为 Integer
        // Arrays.sort(s ,myComparator); // 会报错!//Arrays.sort(a, myComparator);

        // lambda 表达式简写
        Arrays.sort(a, (n1, n2) -> {if (n1 > n2) {return -1;} else {return 1;}
                }
        );
        for (int n : a) {System.out.println(n);
        }
        return s;
    }


    class MyComparator implements Comparator<Integer> {
        @Override
        // 返回正数,零,负数各代表大于,等于,小于
        public int compare(Integer o1, Integer o2) {if (o1 > o2) {return -1;} else {return 1;}
        }


    }
}

作用域

lambda 表达式的方法体与嵌套代码有着相同的作用域。在 lambda 表达式中不允许声明一个与局部变量同名的参数或者局部变量。

// 错误
int first = 0;
Comparator<Integer> comp = (first,second)->first > second

this 指向问题

lambda 表达式中 this 指向创建 lambda 表达式的外部类。

这里的 this 指向 App,而不是 Runnable 实例。这一点和 JavaScript 中的箭头函数很像,this 指向调用此函数的对象。

class App() {public void doWork(){Runnable runnable = ()->{System.out.println(this.toString());
        }
    }
}

lambda 一般情况下会被编译成静态匿名方法,引用的外部变量以参数的方式传递。

如果 lambda 里使用了 this 指标,则被编译为匿名内部方法,以让 this 指针指向 lambda 外部类。

闭包

闭包就是能够读取其他函数内部变量的函数。

这个概念在 JavaScript 中相当重要

https://developer.mozilla.org…

在 Java 中有了 lambda 表达式,也有了闭包的概念,但是和 JavaScript 中的闭包有些不同。没有 JavaScript 中的强大。

import java.util.function.Consumer;
public class Main {public static void main(String[] args) {

        int num = 10;

        Consumer<String> consumer = ele -> {System.out.println(num);
        };

        //num = num + 2;
        consumer.accept("hello");
    }
}

如果把注释删掉,则会报错。因为在 lambda 表达式中只能引用那些值不会改变的变量。

退出移动版