1.引用类方法
其实就是引用某个类中的类方法代替函数式接口中的唯一的一个抽象方法,所以理解了这句话之后,写代码就非常简单了
package 引用类方法;
interface MyLove
{
void print(String name1 , String dig , String name2);/* 定义一个抽象方法,函数式接口 ,用于说明引用类方法 , 并且注意,接口中的抽象方法必须要和调用的方法的形参列表保持一致!!!*/
}
public class LamTest
{
static void Lamprint(String name1 , String dig , String name2)
{
System.out.println(name1 + dig + name2 );
}
public static void main(String[] args)
{
/* MyLove girl = ( name1 , dig , name2)->
{
LamTest.Lamprint(name1 , dig , name2 );
};*/
// 省略Lamprint的所有形参列表和Lambda表达式的所有形参和箭头,以及花括号
// 把类和方法之间的点改为双冒号
MyLove girl = LamTest::Lamprint;// 在工具类中引用所需要的工具方法
girl.print("喜欢的女同学" , "今晚跟" , "我用微信聊天");
// 显然,这里print方法被Lamprint方法代替了,执行接口实例的print方法就是在执行
// LamTest类的Lamprint方法,在函数式接口中被实现的print方法的全部传入的参数
// 全部传到该被引用的类方法里面所以输出了
// 喜欢的女同学今晚跟我用微信聊天
}
}
2.引用特定对象的实例方法
这个的话,疯狂Java讲义里面用的是一个字符串去讲解的
而我自己是直接new了一个对象,大概思路都类似,都差不多
package 引用特定对象的实例方法
interface 这题我不会QwQ
{
void ask(String name1 , String name2); // 用于说明特定对象引用抽象方法
}
public class LamTest
{ // 这里就以随便一个类的实例方法作为要使用的实例方法
void askQuestion(String name1 , String name2)
{
System.out.println(name1 + "在问" + name2 + "问题");
}
public static void main(String[] args)
{
这题我不会QwQ qwq = new LamTest()::askQuestion;/* 生成一个只有一个方法的对象,
方法体是LamTest类的实例方法的代码*/
qwq.ask("喜欢的女同学" , "我");// 调用已经实现了的接口的抽象方法
// 将输出 "喜欢的女同学在问我问题"
}
}
3.引用某类对象的实例方法
这里我曾经和”引用特定对象的实例方法“ , 给弄混淆了,幸好及时发现错误
需要化简的Lambda表达式 形如下面这个形式的 , 以函数式接口的被实现方法的第一个参数作为调用者,后面的参数全部传给该实例方法作为参数,
才可以叫做”引用某类对象的实例方法“``
(a , b , c , …(省略的形参列表) ) ->
{
a.InstanceMethod( b , c , …);
}
package 引用某类对象的实例方法
interface 喜欢的女同学
{
public void print(Girl girl , double high);// 输出其大概的身高
}
class Girl
{
public double high;
public Girl(double high)
{
this.high = high;
}
void invoke(double high)
{
this.printGirl(high);
}
public void printGirl(double high)
{
System.out.println("Girl的身高为" + this.high);
}
}
public class LamTest
{
public static void main(String[] args)
{/* 喜欢的女同学 Mygirl = ( girl , high )->girl.invoke(high);
把形参箭头全部省略掉 , 形参类型,形参书目可以直接从接口里的唯一抽象方法 判断,
接着,直接把需要调用的方法的形参和括号全部省略,
因为jvm知道这是 引用某类对象的实例方法 ,
所以自动省略掉第一个参数,
自动推断剩余的参数就是余下的原来未省略的列表(刨掉第一个参),
接着把第一个参数的改为第一个参数的类名 , 在这里也就是girl -> Girl ,
最后把Girl和其实例方法中的点改为双冒号就可以了 ,
不熟练的可以多重复这个步骤,重复多了下次也就能直接写出双冒号的Lambda引用了*/
喜欢的女同学 Mygirl = Girl::invoke;
Mygirl.print(new Girl(1.70) , 1.70);
// 所以下面将输出Girl的身高为1.70
}
}
4.引用构造器
package 构造器引用
import static java.lang.System.out;
@FunctionalInterface
interface MyGirl
{
Solution askQ(String q);
//其抽象方法的形参列表和Solution构造器的形参列表必须完全相同
//因为函数式接口中的全部参数会传给该构造器作为构造器的参数
}
class Solution // 接口中抽象方法返回的一个对象
{ // 函数式接口中的全部参数传给该构造器作为构造器的参数
Solution(String question)
{
out.println("她问我的" + question + "得到了解答");
}
}
public class LamTest
{
public static void main(String[] args)
{/* 该抽象方法 ,需要生成一个Solution对象 , 即只有一句new 对象语句
我们写出其不用双冒号的Lambda语句
MyGirl mg = (q)-> new Solution("Lambda表达式构造器引用怎么用啊");
接着可以把Solution和Lambda表达式的形参列表连着箭头运算符全部省略,
并把构造器Solution提前到new前面,
把那个new后面的点删除,在构造器和new之间加上双冒号就可以了
重复该过程几次就可以直接写出双冒号的Lambda语句*/
MyGirl mg = Solution::new;
mg.askQ("Lambda表达式构造器引用怎么用啊");
// 下面将输出
// 她问我的Lambda表达式构造器引用怎么用啊得到了解答
}
}