Java基础(下)之方法引用
方法引用
把已经有的方法拿过来用,当做函数式接口中抽象方法的方法体
条件:
- 引用处必须是函数式接口
- 被引用的方法必须已经存在,且形参和返回值需要跟抽象方法保持一致
- 被引用方法的功能要满足当前需求

以数组排序为例:
package com.example.helloworld;
import java.util.*;
class Main{
public static void main(String[] args) throws Exception{
Integer[] arr = {7,3,5,5,6,0,8};
//匿名内部类
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
//lambda表达式
Arrays.sort(arr,(Integer o1,Integer o2)->{
return o2 - o1;
});
//lambda表达式简化格式
Arrays.sort(arr,(o1,o2)->o2 - o1);
//方法引用
Arrays.sort(arr,Main::comp);//表示引用Main类里面的comp方法,把这个方法当做抽象方法的方法体
System.out.println(Arrays.toString(arr));
}
public static int comp(int num1,int num2){
return num2 - num1;
}
}
引用静态方法
格式:类名::静态方法
package com.example.helloworld;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
class Main{
public static void main(String[] args) throws Exception{
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"1","2","3","44","555","6666");
// list.stream()
// .map(new Function<String, Integer>() {
// @Override
// public Integer apply(String str){
// return Integer.parseInt(str);
// }
// })
// .forEach(num-> System.out.println(num));
list.stream()
.map(Integer::parseInt)
.forEach(System.out::println);
}
}
引用成员方法
格式:对象::成员方法
- 其它类:其他类对象::方法名
package com.example.helloworld;
import java.util.*;
class Main{
public static void main(String[] args) throws Exception{
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"张三丰","李佳铭","张伦达","赵四","张涛");
// list.stream()
// .filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
// return s.length() == 3 && s.startsWith("张");
// }
// })
// .forEach(name->System.out.println(name));
list.stream()
.filter(new StringOperation()::check)
.forEach(System.out::println);
}
}
class StringOperation{
public boolean check(String s){
return s.length() == 3 && s.startsWith("张");
}
}
- 本类:this::方法名
注意:引用处不能是静态方法,因为静态方法没有this - 父类:super::方法名
注意:引用处不能是静态方法,因为静态方法没有this
package com.example.helloworld;
import java.util.*;
class Father{
public void func(String str){
System.out.println("Father's func is called!");
}
}
class Main extends Father{
public void main(String[] args) throws Exception{
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"张三丰","李佳铭","张伦达","赵四","张涛");
// list.stream()
// .filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
// return s.length() == 3 && s.startsWith("张");
// }
// })
// .forEach(name->System.out.println(name));
//等价于上面代码块
list.stream()
.filter(new StringOperation()::check)//引用其它类方法
.forEach(System.out::println);//引用其它类方法
list.stream()
.forEach(this::func);//引用本类方法
list.stream()
.forEach(super::func);//引用父类方法
}
public void func(String str){
System.out.println("Main's func is called!");
}
}
class StringOperation{
public boolean check(String s){
return s.length() == 3 && s.startsWith("张");
}
}
引用构造方法
格式:类名::new
package com.example.helloworld;
import java.util.*;
import java.util.stream.Collectors;
class Student{
String name;
int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public Student(String str){
String[] strs = str.split(",");
this.name = strs[0];
this.age = Integer.parseInt(strs[1]);
}
@Override
public String toString() {
return this.name + " " + Integer.toString(this.age);
}
}
class Main {
public void main(String[] args) throws Exception{
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"张三丰,15","李佳铭,16","张伦达,21","赵四,24","张涛,25");
// List<Student> list1 = list.stream()
// .map(new Function<String, Student>() {
// @Override
// public Student apply(String s) {
// String[] strs = s.split(",");
// String name = strs[0];
// int age = Integer.parseInt(strs[1]);
// return new Student(name,age);
// }
// })
// .collect(Collectors.toList());
// System.out.println(list1);
//等价于上面代码块
List<Student> list2 = list.stream()
.map(Student::new)//引用构造方法
.collect(Collectors.toList());
System.out.println(list2);
}
}
使用类名引用成员方法
格式:类名::成员方法
独特规则:
- 被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致;
形参的详解:
第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法。在Stream流中,第一个参数一般表示流中的每一个数据。假设Stream中的数据是字符串,则只能引用String这个类中的方法
剩余参数:与被引用方法的形参保持一致,若没有第二个参数,说明被引用的方法需要的是无参的成员方法
package com.example.helloworld;
import java.util.*;
class Main {
public void main(String[] args) throws Exception{
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"aaa","bbb","ccc","ddd");
// list.stream()
// .map(new Function<String, String>() {
// @Override
// public String apply(String s) {
// return s.toUpperCase();
// }
// })
// .forEach(s -> System.out.println(s));
//等价上面代码块
list.stream()
.map(String::toUpperCase) //引用其它类的成员函数
.forEach(System.out::println);
}
}
引用数组的构造方法
格式:数据格式[]::new
独特规则:
- 数组的类型,需要和流中数据的类型保持一致。
package com.example.helloworld;
import java.util.*;
class Main {
public void main(String[] args) throws Exception{
ArrayList<String>list = new ArrayList<>();
Collections.addAll(list,"aaa","bbb","ccc","ddd");
// String[] arr1 = list.stream()
// .toArray(size->new String[size]);
// System.out.println(Arrays.toString(arr1));
String[] arr2 = list.stream()
.toArray(String[]::new);//引用数组的构造方法
System.out.println(Arrays.toString(arr2));
}
}

浙公网安备 33010602011771号