方法引用
方法: 就是以前學過的方法.
引用: 就是把已有的方法拿過來用.
如何用: 當做函式式介面抽象方法的方法體.
總結: 方法引用就是把已經有的方法拿過來用, 當做函式式介面中抽象方法的方法體.
方法引用的條件:
-
引用處必須是函式式介面.
-
被引用的方法必須是已經存在的.
-
被引用方法的形參和返回值必須和抽象方法保持一致.
-
被引用的方法的功能要能滿足當前的要求.
::
是方法引用符.
示例:
引用靜態方法
格式: 類名::靜態方法
範例: Integer::parseInt
程式示例:
import java.util.ArrayList;
import java.util.Collections;
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));
}
}
引用成員方法
格式: 物件::成員方法
其他類: 其他類物件::方法名
本類: this::方法名
父類: super::方法名
程式示例:
import java.util.ArrayList;
import java.util.Collections;
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;
}
}
程式示例:
public class App {
public static void main(String[] args) {
new LoginJFrame();
}
}
import javax.swing.*;
import java.awt.*;
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); // 置頂
}
}
import javax.swing.*;
import java.awt.event.ActionEvent;
public class MyJFrame extends JFrame {
public void method1(ActionEvent e) {
System.out.println("go按鈕被點選了");
}
}
引用構造方法
格式: 類名::new
範例: Student::new
程式示例:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
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::substring
程式示例:
import java.util.ArrayList;
import java.util.Collections;
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
範例: int[]::new
程式示例:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
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.列印
}
}