方法引用概述
方法引用是Java 8引入的Lambda表达式的一种简化写法,用于直接引用已有的方法。它通过::符号连接目标对象或类与方法名,适用于函数式接口的实现。方法引用分为静态方法引用、实例方法引用、构造方法引用等类型。
实例:
public class FunctionDemo1 {
public static void main(String[] args) {
//需求:创建一个数组,进行倒序排列
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;
}
});*/
//lambda表达式
//因为第二个参数的类型Comparator是一个函数式接口
/* Arrays.sort(arr, (Integer o1, Integer o2)->{
return o2 - o1;
});*/
//lambda表达式简化格式
//Arrays.sort(arr, (o1, o2)->o2 - o1 );
//方法引用
//1.引用处需要是函数式接口
//2.被引用的方法需要已经存在
//3.被引用方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
//4.被引用方法的功能需要满足当前的要求
//表示引用FunctionDemo1类里面的subtraction方法
//把这个方法当做抽象方法的方法体
Arrays.sort(arr, FunctionDemo1::subtraction);
System.out.println(Arrays.toString(arr));
}
//可以是Java已经写好的,也可以是一些第三方的工具类
public static int subtraction(int num1, int num2) {
return num2 - num1;
}
}
引用静态方法
语法:类名::静态方法名
适用于引用类的静态方法,传递给函数式接口时要求参数和返回值匹配。
// 示例:引用Integer的静态方法parseInt
Function<String, Integer> converter = Integer::parseInt;
System.out.println(converter.apply("123")); // 输出: 123
实例:
public class FunctionDemo2 {
public static void main(String[] args) {
/*
方法引用(引用静态方法)
格式
类::方法名
需求:
集合中有以下数字,要求把他们都变成int类型
"1","2","3","4","5"
*/
//1.创建集合并添加元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"1","2","3","4","5");
//2.把他们都变成int类型
/* list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
int i = Integer.parseInt(s);
return i;
}
}).forEach(s -> System.out.println(s));*/
//1.方法需要已经存在
//2.方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
//3.方法的功能需要把形参的字符串转换成整数
list.stream()
.map(Integer::parseInt)
.forEach(s-> System.out.println(s));
}
}
引用其他类的成员方法
语法:对象实例::实例方法名
适用于通过对象实例引用其非静态方法。
// 示例:引用String的实例方法toUpperCase
String str = "hello";
Supplier<String> supplier = str::toUpperCase;
System.out.println(supplier.get()); // 输出: HELLO
实例:
public class FunctionDemo3 {
public static void main(String[] args) {
/*
方法引用(引用成员方法)
格式
其他类:其他类对象::方法名
本类:this::方法名(引用处不能是静态方法)
父类:super::方法名(引用处不能是静态方法)
需求:
集合中有一些名字,按照要求过滤数据
数据:"张无忌","周芷若","赵敏","张强","张三丰"
要求:只要以张开头,而且名字是3个字的
*/
//1.创建集合
ArrayList<String> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");
//3.过滤数据(只要以张开头,而且名字是3个字的)
//list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(s-> System.out.println(s));
/* list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张") && s.length() == 3;
}
}).forEach(s-> System.out.println(s));*/
/* StringOperation so = new StringOperation();
list.stream().filter(so::stringJudge)
.forEach(s-> System.out.println(s));*/
//静态方法中是没有this的
list.stream().filter(new FunctionDemo3()::stringJudge)
.forEach(s-> System.out.println(s));
}
public boolean stringJudge(String s){
return s.startsWith("张") && s.length() == 3;
}
}
public class StringOperation {
public boolean stringJudge(String s){
return s.startsWith("张") && s.length() == 3;
}
}
引用本类或父类的成员方法
语法:this::实例方法名 或 super::父类方法名
适用于当前类或父类中定义的实例方法。
class Parent {
void print() {
System.out.println("Parent method");
}
}
class Child extends Parent {
void invokeMethods() {
Runnable parentMethod = super::print;
Runnable childMethod = this::printChild;
parentMethod.run(); // 输出: Parent method
childMethod.run(); // 输出: Child method
}
void printChild() {
System.out.println("Child method");
}
}
实例:
public class LoginJFrame extends MyJFrame {
JButton go = new JButton("Go");
public LoginJFrame() {
//设置图标
setIconImage(Toolkit.getDefaultToolkit().getImage("myfunction\\image\\logo.jpg"));
//设置界面
initJframe();
//添加组件
initView();
//界面显示出来
this.setVisible(true);
}
//添加组件
public void initView() {
JLabel image = new JLabel(new ImageIcon("myfunction\\image\\kit.jpg"));
image.setBounds(100,50,174,174);
this.getContentPane().add(image);
go.setFont(new Font(null,1,20));
go.setBounds(120,274,150,50);
go.setBackground(Color.WHITE);
go.addActionListener(super::method1);
this.getContentPane().add(go);
}
//设置界面
public void initJframe() {
//设置标题
this.setTitle("随机点名器");
//设置大小
this.setSize(400, 500);
//设置关闭模式
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗口无法进行调节
this.setResizable(false);
//界面居中
this.setLocationRelativeTo(null);
//取消内部默认居中放置
this.setLayout(null);
//设置背景颜色
this.getContentPane().setBackground(Color.white);
this.setAlwaysOnTop(true);//置顶
}
}
public class MyJFrame extends JFrame {
public void method1(ActionEvent e) {
System.out.println("go按钮被点击了");
}
}
public class App {
public static void main(String[] args) {
new LoginJFrame();
}
}
引用构造方法
语法:类名::new
适用于通过函数式接口创建对象实例。
// 示例:引用String的构造方法
Function<String, String> stringConstructor = String::new;
System.out.println(stringConstructor.apply("new string")); // 输出: new string
实例:
public class FunctionDemo4 {
public static void main(String[] args) {
/*
方法引用(引用构造方法)
格式
类名::new
目的:
创建这个类的对象
需求:
集合里面存储姓名和年龄,要求封装成Student对象并收集到List集合中
方法引用的规则:
1.需要有函数式接口
2.被引用的方法必须已经存在
3.被引用方法的形参和返回值,需要跟抽象方法的形参返回值保持一致
4.被引用方法的功能需要满足当前的需求
*/
//1.创建集合对象
ArrayList<String> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
//3.封装成Student对象并收集到List集合中
//String --> Student
/* List<Student> newList = list.stream().map(new Function<String, Student>() {
@Override
public Student apply(String s) {
String[] arr = s.split(",");
String name = arr[0];
int age = Integer.parseInt(arr[1]);
return new Student(name, age);
}
}).collect(Collectors.toList());
System.out.println(newList);*/
List<Student> newList2 = list.stream().map(Student::new).collect(Collectors.toList());
System.out.println(newList2);
}
}
public class Student {
private String name;
private int age;
public Student() {
}
//重点注意:自己创建的构造方法
public Student(String str) {
String[] arr = str.split(",");
this.name = arr[0];
this.age = Integer.parseInt(arr[1]);
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
类名引用成员方法
语法:类名::实例方法名
适用于将类的实例方法作为函数式接口的实现,第一个参数为方法调用者。
// 示例:引用String的compareToIgnoreCase方法
BiFunction<String, String, Integer> comparator = String::compareToIgnoreCase;
System.out.println(comparator.apply("A", "a")); // 输出: 0(忽略大小写比较)
实例:
public class FunctionDemo5 {
public static void main(String[] args) {
/*
方法引用(类名引用成员方法)
格式
类名::成员方法
需求:
集合里面一些字符串,要求变成大写后进行输出
方法引用的规则:
1.需要有函数式接口
2.被引用的方法必须已经存在
3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致。
4.被引用方法的功能需要满足当前的需求
抽象方法形参的详解:
第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
在Stream流当中,第一个参数一般都表示流里面的每一个数据。
假设流里面的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法
第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法
局限性:
不能引用所有类中的成员方法。
是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法。
*/
//1.创建集合对象
ArrayList<String> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list, "aaa", "bbb", "ccc", "ddd");
//3.变成大写后进行输出
//map(String::toUpperCase)
//拿着流里面的每一个数据,去调用String类中的toUpperCase方法,方法的返回值就是转换之后的结果。
list.stream().map(String::toUpperCase).forEach(s -> System.out.println(s));
//String --> String
/* list.stream().map(new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
}).forEach(s -> System.out.println(s));*/
}
}
引用数组的构造方法
语法:数据类型[]::new
适用于创建指定长度的数组。
// 示例:引用Integer数组的构造方法
Function<Integer, Integer[]> arrayCreator = Integer[]::new;
Integer[] array = arrayCreator.apply(3); // 创建长度为3的Integer数组
System.out.println(array.length); // 输出: 3
实例:
public class FunctionDemo6 {
public static void main(String[] args) {
/*
方法引用(数组的构造方法)
格式
数据类型[]::new
目的:
创建一个指定类型的数组
需求:
集合中存储一些整数,收集到数组当中
细节:
数组的类型,需要跟流中数据的类型保持一致。
*/
//1.创建集合并添加元素
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4, 5);
//2.收集到数组当中
Integer[] arr2 = list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(arr2));
/*Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});*/
//3.打印
}
}
通过方法引用,可以简化代码并提升可读性,尤其在Stream API和函数式编程中广泛应用。需注意目标方法的参数和返回值需与函数式接口匹配。
170万+

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



