一.概述:
1.分类:

2.方法引用需要分成方法和引用两部分进行理解:

3.总结:

-
弊端:可读性差
二.方法引用过程:

1.Arrays是操作数组的工具类,sort方法用于对数组进行排序,sort方法是静态即被static修饰,第一个参数arr是数组名
2.第二个参数是一个函数式接口,用于指定排序规则,需要传递Comparator接口的实现类对象,由于Comparator接口是函数式接口,所以可以用Lambda表达式进行简化,但Lambda表达式并不是最优解,它还可以进一步优化,下图中红圈画起来的地方即排序规则可以不用写,可以把已经存在的方法直接拿过来用,把已经存在的方法当作是函数式接口中抽象方法的方法体:




3.比如现在有一个已经写好的subtraction方法,那么在sort方法的第二个参数中就可以直接使用subtraction方法,这就是方法引用:

三.使用方法引用的前提条件:

1.引用处必须是函数式接口;
2.被引用的方法必须是已经存在的:
-
如果要被引用的方法不存在,就需要自行编写
-
被引用的方法可以是Java已经写好的,可以是自行编写的,也可以是一些第三方的工具类
-
第三方代码不是Java写的,也不是我们自己写的,是第三个人写的代码
3.被引用的方法的形参(包括形参类型,形参类型的顺序,形参的个数)和返回值类型需要分别和抽象方法的形参(包括形参类型,形参类型的顺序,形参的个数)和返回值类型保持一致 :方法命名和形参的命名无需一致,命名见名知意即可
举例:

上述图片左侧中Comparator接口中有一个抽象方法compare,这个方法的形参是两个整型变量o1、o2,返回值也是整型int,而且返回的是第二个参数减第一个参数,
要被引用的subtraction方法的形参也是两个整型变量n1,n2,返回值也是整型int,返回的也是第二个参数减第一个参数,
所以compare方法和subtraction方法就对应起来了,形参的个数和数据类型都一样,返回值类型和返回值功能也都一样。
(形参的变量名没有要求)
4.被引用的方法的功能需要满足当前的需求:

被引用的subtraction方法他是用来做减法的,而且是第二个参数减第一个参数,并把结果返回,
在compare方法中也是第二个参数减第一个参数,并把结果返回,
所以subtraction方法和compare方法的功能是一样的
->subtraction方法满足方法引用的条件,而且在引用处是函数式接口,所以sort方法的第二个参数就可以用subtraction方法进行简化。
四.实例:
要求:创建一个数组,进行倒序排列即从大到小排列
法一:匿名内部类
package com.itheima.a01myfunction;
import java.util.Arrays;
import java.util.Comparator;
public class FunctionDemo1 {
public static void main(String[] args) {
//需求:创建一个数组,进行倒序排列即从大到小排列
/*数组中的数据为整型,用Arrays类里的sort方法进行排列的话
系统默认排序是正序排列即从小到大排列,如果
要倒序排列就需要自定义排序规则,此时数组类型就要用包装类*/
Integer[] arr={3,5,4,1,6,2};
//匿名内部类
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(Arrays.toString(arr)); //运行结果为[6, 5, 4, 3, 2, 1]
}
}
法二:lambda表达式

package com.itheima.a01myfunction;
import java.util.Arrays;
public class FunctionDemo1 {
public static void main(String[] args) {
//需求:创建一个数组,进行倒序排列即从大到小排列
/*数组中的数据为整型,用Arrays类里的sort方法进行排列的话
系统默认排序是正序排列即从小到大排列,如果
要倒序排列就需要自定义排序规则,此时数组类型就要用包装类*/
Integer[] arr={3,5,4,1,6,2};
//lambda表达式
/*因为sort方法的第二个参数的类型Comparator是一个函数式接口,
而且此时Comparator接口是匿名内部类,
所以可以使用lambda表达式 */
Arrays.sort(arr, (Integer o1, Integer o2) -> {
return o2-o1;
});
System.out.println(Arrays.toString(arr)); //运行结果为[6, 5, 4, 3, 2, 1]
}
}
法三:简化lambda表达式
package com.itheima.a01myfunction;
import java.util.Arrays;
public class FunctionDemo1 {
public static void main(String[] args) {
//需求:创建一个数组,进行倒序排列即从大到小排列
/*数组中的数据为整型,用Arrays类里的sort方法进行排列的话
系统默认排序是正序排列即从小到大排列,如果
要倒序排列就需要自定义排序规则,此时数组类型就要用包装类*/
Integer[] arr={3,5,4,1,6,2};
//简化lambda表达式
Arrays.sort(arr, (o1,o2) -> o2-o1);
System.out.println(Arrays.toString(arr)); //运行结果为[6, 5, 4, 3, 2, 1]
}
}
法四:方法引用
package com.itheima.a01myfunction;
import java.util.Arrays;
public class FunctionDemo1 {
public static void main(String[] args) {
//需求:创建一个数组,进行倒序排列即从大到小排列
/*数组中的数据为整型,用Arrays类里的sort方法进行排列的话
系统默认排序是正序排列即从小到大排列,如果
要倒序排列就需要自定义排序规则,此时数组类型就要用包装类*/
Integer[] arr={3,5,4,1,6,2};
/*
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
*/
//方法引用
/*使用方法引用的条件:
1.引用处必须是函数式接口
2.被引用的方法需要已经存在,没有的话就需要自行编写
3.被引用的方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
4.被引用的方法的功能需要满足当前的需求 */
//subtraction方法满足sort方法的Comparator接口处使用方法引用
/* subtraction方法是静态方法,静态方法需要通过类名.方法名来调用,在方法引用中也是如此,
FunctionDemo1::subtraction表示引用FunctionDemo1类里面的subtraction方法,
把subtraction方法当作抽象方法的方法体 */
Arrays.sort(arr,FunctionDemo1::subtraction);
System.out.println(Arrays.toString(arr)); //运行结果为[6, 5, 4, 3, 2, 1]
}
public static int subtraction(int num1,int num2){
return num2-num1;
}
}
五.总结:


六.技巧:使用方法引用改写前要思考的问题
1.现在有没有一个方法符合我当前的需求;
2.如果有这样的方法,这个方法是否满足方法引用的规则:
如果满足,
对于静态方法:类名::方法名;
对于成员方法(非静态方法):如果要引用的方法在当前类中,就类名::方法名;如果要引用的方法在其他类中,就对象名::方法名;如果要引用的方法在本类中,就this::方法名;如果要引用的方法在父类中,就super::方法名;
对于构造方法:类名::new;

被折叠的 条评论
为什么被折叠?



