PDF 课件和源代码下载地址:
https://gitee.com/geektime-geekbang/LetsJava
作者回复: ✅👍 设 M super T,那么M就是T的父类或者就是T本身(重),那么对于List<T>来说,范型本身的约束就是让List里的元素是T类型或者其子类(重)。 所以M肯定是T的父类/本身,List里的元素肯定是子类/本身。因此M的引用可以指向List里的元素👌,所以下面代码里,t当作Consumer的参数没问题。 default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
作者回复: 相信我,你这种学不明白就写写看,写不明白就问问看的方法,就没有学不会的东西👍 回到你的问题,你说的完全正确。lambda的接口只能有一个抽象方法。Java也是用这个抽象方法,再移花接木的一顿操作,最终调用了你写的代码。 你这学习方式太赞了!
作者回复: 在我看来,这其实是一种函数式编程的“恶趣味”,或者是一个标榜的优势:极力压缩代码量,压缩局部变量的创建(当然也挺好,毕竟我们写代码百分之九十的时间是在给变量方法类起名字😄)。 回到你的问题,我说的外部参数,就是除了lambda要遍历和处理的那个值之外的参数。这样就可以在没有二义性的前提下极力压缩代码量了
作者回复: 接着看,后面都有的
作者回复: 是的,lambda只能有一个方法
作者回复: 这种刨根问底的学习态度必须点个大大的赞👍👍
作者回复: 体会1: lambda从最终的功能来说,更多的是方便,而且Java基础类库也增加了lambda接口的支持。相当于是标准化了。其实如果愿意的话接口就是lambda。一点解释:并非是之前的Java无法做到传递代码的功能,只是不标准不方便,就无法得到大规模应用。 体会2: 这俩行为是ArrayList的行为,但是也不仅仅是它的行为呀。Set也可以。所以用接口把这种遍历、操作元素的行为独立出来。谁想实现谁就用这个接口
作者回复: 那你看看是谁调用的process String呢?debugger可能会有一些调用栈上的优化。可以new一个exception,然后printStackTrace看看实际的调用栈。
作者回复: 这个就是lambda语句,最终会翻译成一些完成lambda需要的代码,当然完成功能的还是new String
作者回复: 很棒棒哦,lambda其实有点绕的。