一.方法引用
1.概念:把已经有的方法拿过来用,当作函数式接口中抽象方法的方法体
2.使用方法引用之前需要满足的规则
(1).引用处必须是函数式接口
(2).被引用的方法必须已经存在(如果不存在就需要自己写)
(3).被引用方法的形参和返回值需要跟抽象方法保持一致
(4).被引用方法的功能要满足当前需求
例题:
创建一个数组,进行倒序排列
import java.util.Arrays;
import java.util.Comparator;public class FunctionReference {public static void main(String[] args) {Integer[] arr = {7, 5, 3, 6, 9, 1, 4, 8, 2};//匿名内部类Arrays.sort(arr, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});System.out.println(Arrays.toString(arr));//Lambda表达式Arrays.sort(arr, (Integer o1, Integer o2) -> {return o2 - o1;});System.out.println(Arrays.toString(arr));//方法引用Arrays.sort(arr, FunctionReference::substraction);System.out.println(Arrays.toString(arr));}private static int substraction(Integer o1, Integer o2) {return o2 - o1;}
}
(::是方法引用符 )
二.方法引用的分类
1.引用静态方法
格式:类名::静态方法
范例:Integer::parseInt
练习:
集合中有以下数字,要求把它们都变成int类型
"1","2","3","4","5"
import java.util.ArrayList;
import java.util.Collections;public class FunctionReference {public static void main(String[] args) {ArrayList<String> str = new ArrayList<>();Collections.addAll(str, "1", "2", "3", "4", "5");ArrayList<Integer> number = new ArrayList<>();str.stream().map(Integer::parseInt).forEach(integer -> System.out.println(integer));}
}
2.引用成员方法
格式:
对象::成员方法
(1).引用其他类的成员方法
引用其他类的成员方法的格式:其他类对象::方法名
import java.util.ArrayList;
import java.util.Collections;public class FunctionReference {public static void main(String[] args) {ArrayList<String> al = new ArrayList<>();Collections.addAll(al, "张无忌", "周芷若", "赵敏", "张强", "张三丰");al.stream().filter(StringFunction::judge).forEach(s -> System.out.println(s));}
}
StringFunction:
public class StringFunction {public static boolean judge(String s) {return s.startsWith("张") && s.length() == 3;}
}
(2).引用本类的成员方法
引用本类的成员方法的格式:本类:this::方法名
练习1:
集合中有一些名字,按照要求过滤数据
数据:"张无忌","周芷若","赵敏","张强","张三丰"
要求:只要以张开头且名字长度是3的数据
import java.util.ArrayList;
import java.util.Collections;public class FunctionReference {public static void main(String[] args) {ArrayList<String> al = new ArrayList<>();Collections.addAll(al, "张无忌", "周芷若", "赵敏", "张强", "张三丰");//注意:静态方法中是没有this的,所以这里的FunctionReference(即类名)不能换做this,否则会报错al.stream().filter(FunctionReference::judge).forEach(s -> System.out.println(s));}public static boolean judge(String s) {return s.startsWith("张") && s.length() == 3;}
}
练习2:
GUI界面中点击事件的方法引用写法
Frame:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;public class Frame extends JFrame {JButton GO = new JButton("GO");public Frame() {initFram();initView();this.setVisible(true);}private void initFram() {this.setTitle("Frame");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);}private void initView() {GO.setFont(new Font(null, 1, 20));GO.setBounds(120, 150, 150, 50);GO.setBackground(Color.WHITE);GO.addActionListener(this::click);this.getContentPane().add(GO);}public void click(ActionEvent e) {Object o = e.getSource();if (o == GO) {System.out.println("GO");}}
}
public class FunctionReference {public static void main(String[] args) {new Frame();}
}
(3).引用父类的成员方法
引用父类的成员方法的格式:父类:super::方法名
练习2:
GUI界面中点击事件的方法引用写法
Frame:
import javax.swing.*;
import java.awt.*;public class Frame extends FatherFrame {JButton GO = new JButton("GO");public Frame() {initFram();initView();this.setVisible(true);}private void initFram() {this.setTitle("Frame");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);}private void initView() {GO.setFont(new Font(null, 1, 20));GO.setBounds(120, 150, 150, 50);GO.setBackground(Color.WHITE);GO.addActionListener(super::click);this.getContentPane().add(GO);}
}
FatherFrame:
import javax.swing.*;
import java.awt.event.ActionEvent;public class FatherFrame extends JFrame {public void click(ActionEvent e) {System.out.println("GO");}
}
public class FunctionReference {public static void main(String[] args) {new Frame();}
}
(注意在引用父类和本类的成员方法且使用this/super的格式时,引用处不能是静态方法,因为静态方法中没有this和super关键字,会报错)
3.引用构造方法
格式:类名::new
范例:Student::new
练习:
集合里面存储姓名和年龄,比如:A,18
要求:将数据封装成Student对象并收集到List集合中
Student里的属性:String name,int age
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;public class FunctionReference {public static void main(String[] args) {ArrayList<String> al = new ArrayList<>();Collections.addAll(al, "A,18", "B,19", "C,20", "D,21", "E,22");/*没有引用构造方法List<Student> collect = al.stream().map(new Function<String, Student>() {@Overridepublic Student apply(String s) {String[] str = s.split(",");String name = str[0];int age = Integer.parseInt(str[1]);return new Student(name, age);}}).collect(Collectors.toList());System.out.println(collect);*///引用构造方法List<Student> collect = al.stream()//这里记得回到Student类中写一个只有一个参数的构造方法,以匹配引用成员方法的规则,否则在下方会报错.map(Student::new).collect(Collectors.toList());System.out.println(collect);}
}
4.其他引用方式
(1).使用类名引用成员方法
格式:类名::成员方法
范例:String::substring
练习:
集合里面存有一些字符串,要求变成大写后进行输出
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;public class FunctionReference {public static void main(String[] args) {ArrayList<String> al = new ArrayList<>();Collections.addAll(al, "aaa", "bbb", "ccc", "ddd", "eee");/*没有进行引用al.stream().map(new Function<String, String>() {@Overridepublic String apply(String s) {return s.toUpperCase();}}).forEach(s -> System.out.println(s));*/al.stream().map(String::toUpperCase).forEach(s -> System.out.println(s));}
}
(2).引用数组的构造方法
格式:数据类型[]::new
范例:int[]::new
练习:
集合中存储了一些整形数据,将它们收集到数组当中
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;public class FunctionReference {public static void main(String[] args) {ArrayList<Integer> al = new ArrayList<>();Collections.addAll(al, 1, 2, 3, 4, 5, 6, 7, 8, 9);/*没有进行引用Integer[] arr = al.stream().toArray(new IntFunction<Integer[]>() {@Overridepublic Integer[] apply(int value) {return new Integer[value];}});System.out.println(Arrays.toString(arr));*/Integer[] arr=al.stream().toArray(Integer[]::new);System.out.println(Arrays.toString(arr));}
}