方法引用:就是把已经有的方法拿过来用,当作函数式接口抽象方法的方法体。
条件

  1. 引用处必须是函数式接口
  2. 被引用的方法必须已经存在
  3. 被引用方法的形参和返回值需要和抽象方法保持一致
  4. 被引用的方法要满足当前需求

格式:类名::方法名


引例

public class Demo01 {
// 被引用的方法:可以是java已经写好的,也可以是第三方工具类
public static int sub(int a, int b) {
return a - b;
}
public static void main(String[] args) {
Integer[] arr = {3, 5, 4, 1, 6, 2};
// lambda表达式
Arrays.sort(arr, (o1, o2) -> o1 - o2);
System.out.println(Arrays.toString(arr));
// 改进:方法引用
Arrays.sort(arr, Demo01::sub); // 类名::方法名
}
}

引用静态方法

格式:类名::静态方法

public class Demo02 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "4", "5");
List<Integer> list1 = list.stream().map(Integer::parseInt)
.collect(Collectors.toList());
}
}

引用成员方法

格式:对象::成员方法

  1. 其他类:其它类对象::方法名
  2. 本类:this::方法名
  3. 父类:super::方法名
public class Demo03 {
public boolean StringJudge(String s) {
return s.startsWith("张") && s.length() == 3;
}
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");
List<String> list1 = list.stream().filter(new Demo03()::StringJudge)
.collect(Collectors.toList());
}
}

注:引用本类成员方法、父类成员方法处不能是静态方法

引用构造方法

格式:类名::new

class Student {
private String name;
private Integer no;
// 流里边的数据是string,所以这里形参需要写string
Student(String str) {
String[] split = str.split("-");
this.name = split[0];
this.no = Integer.valueOf(split[1]);
}
}
public class Demo04 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-1", "周芷若-2", "赵敏-3", "张三丰-4", "张翠山-5", "张良-6", "王二麻子-7", "谢广坤-8");
List<Student> list1 = list.stream().map(Student::new)
.collect(Collectors.toList());
}
}

其他调用方式

使用类名引用成员方法

public class Demo05 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c");
List<String> list1 = list.stream()
// 拿着流里的数据,去调用String类中的toUpperCase方法,返回值就是转换后的结果
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(list1);
}
}

【注】:被引用方法的形参需要跟抽象方法的第二个形参到最后一个形参保持一致
13727fe029cd4c4b97be59bd9718328f.png

  1. 第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
    在stream流中,第一个参数一般都表示流里边每个数据,假设流里边的数据是字符串,那么只能引用String这个类中的方法
  2. 第二个参数到最后一个参数:和被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法

引用数组的构造方法

格式:数据类型[]::new

public class Demo06 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c");
String[] array = list.stream()
.toArray(String[]::new); // 数组中的类型需要和流中数据的类型保持一致
}
}