当前位置:网站首页>Lambda expression 2: method reference
Lambda expression 2: method reference
2022-07-18 08:42:00 【Xiao Wang who became a monk halfway】
Catalog
3. Use method reference to improve code
5. Reference member methods by object name
6. Reference static methods by class name
7. adopt super Reference member methods
8. adopt this Reference member methods
9. Constructor reference for class
10. Array constructor reference
In the use of Lambda In terms of expression , The code we actually pass in is a solution : What to do with what parameters . So consider a situation : If we were Lambda The operation scheme specified in , There are already places where the same scheme exists , Is it necessary to write repetitive logic again ?
1. Redundant Lambda scene
Look at a simple functional interface to apply Lambda expression :
@FunctionalInterface
public interface Printable{
voidprint(Stringstr);
} stay Printable The only abstract method in the interface print Receive a string parameter , The purpose is to print and display it . Then through the Lambda The code to use it is simple :
public class Demo01PrintSimple {
private static void printString(Printable data) {
data.print("Hello, World!");
}
public static void main(String[] args) {
printString(s ‐> System.out.println(s));
}
} among printString Method just calls Printable Interface print Method , And don't care print Method, where will the string be printed . and main Methods by Lambda Expression specifies a functional interface Printable The specific operation scheme is : Get String( Types can be derived , So you can omit ) After the data , Output it in the console .
2. Problem analysis
The problem with this code is , Operation scheme for console printout of string , Obviously, there is a ready-made implementation , That's it System.out Object println(String) Method . since Lambda All you want to do is call println(String) Method , Then why call it manually ?
3. Use method reference to improve code
Can you spare Lambda The grammar of ( Although it has been quite concise ) Well ? as long as “ quote ” The past is good :
public class Demo02PrintRef {
private static void printString(Printable data) {
data.print("Hello, World!");
}
public static void main(String[] args) {
printString(System.out::println);
}
} Please note that Double colon :: How to write it , This is known as “ Method reference ”, And double colons are a new syntax .
4. Method references
Double colon :: Is a reference operator , And the expression it's in is called a method reference . If Lambda The function scheme to be expressed already exists in the implementation of a method , Then you can use double colons to refer to this method as Lambda The replacement of .
Semantic analysis
In the example above , System.out Object has an overloaded println(String) The method is exactly what we need . So for printString Method's functional interface parameters , Compare the following two ways , Completely equivalent :
Lambda Expression writing :
s -> System.out.println(s);Method quotation method :
System.out::println
The first semantics refers to : After getting the parameters, go through Lambda In the hands of , Then pass it on to System.out.println How to deal with . The semantics of the second equivalent expression refers to : Directly to System.out Medium println Method to replace Lambda. The execution effect of the two writing methods is exactly the same , The second method refers to the writing method that reuses the existing scheme , More concise .
notes :Lambda in Parameters passed It must be in the method reference The type that the method can receive , Otherwise, an exception will be thrown
Derivation and omission
If you use Lambda, So according to “ Deducible means omitable ” Principles , There is no need to specify the parameter type , There is no need to specify the overload form —— Both of them Will be automatically derived . And if you use method references , It can also be inferred from context .
The functional interface is Lambda The basis of , And the method quote is Lambda Twin brother . The following code will call println Different overloaded forms of methods , Change the functional interface to int Parameters of type :
@FunctionalInterface
public interface PrintableInteger {
void print(int str);
}As the context changes, the unique matching overload can be automatically deduced , So there is no change in the method reference :
public class Demo03PrintOverload {
private static void printInteger(PrintableInteger data) {
data.print(1024);
}
public static void main(String[] args) {
printInteger(System.out::println);
}
} This method reference will automatically match to println(int) Overloaded form of .
5. Reference member methods by object name
This is the most common usage , Same as above . If a member method already exists in a class :
public class MethodRefObject {
public void printUpperCase(String str) {
System.out.println(str.toUpperCase());
}
}Functional interfaces are still defined as :
@FunctionalInterface
public interface Printable {
void print(String str);
} So when you need to use this printUpperCase Member method to replace Printable Interface Lambda When , Already has MethodRefObject Object instance of class , Member methods can be referenced by object names , The code is :
public class Demo04MethodRef {
private static void printString(Printable lambda) {
lambda.print("Hello");
}
public static void main(String[] args) {
MethodRefObject obj = new MethodRefObject();
printString(obj::printUpperCase);
}
}6. Reference static methods by class name
Because in java.lang.Math Static methods already exist in class abs , So when we need to go through Lambda To call the method , There are two ways of writing . The first is the functional interface :
@FunctionalInterface
public interface Calcable {
int calc(int num);
} The first way is to use Lambda expression :
public class Demo05Lambda {
private static void method(int num, Calcable lambda) {
System.out.println(lambda.calc(num));
}
public static void main(String[] args) {
method(‐10, n ‐> Math.abs(n));
}
}But a better way to use method references is :
public class Demo06MethodRef {
private static void method(int num, Calcable lambda) {
System.out.println(lambda.calc(num));
}
public static void main(String[] args) {
method(‐10, Math::abs);
}
} In this case , The following two expressions are equivalent :
Lambda expression :
n -> Math.abs(n)Method reference :
Math::abs
7. adopt super Reference member methods
If there is an inheritance relationship , When Lambda Need to appear in super Invocation time , You can also use method references instead of . The first is the functional interface :
@FunctionalInterface
public interface Greetable {
void greet();
} Then the parent class Human The content of :
public class Human {
public void sayHello() {
System.out.println("Hello!");
}
} Finally, there are subclasses Man The content of , It uses Lambda Writing :
public class Man extends Human {
@Override
public void sayHello() {
System.out.println(" Hello everyone , I am a Man!");
}
// Define methods method, Parameter passing Greetable Interface
public void method(Greetable g){
g.greet();
}
public void show(){
// call method Method , Use Lambda expression
method(()‐>{
// establish Human object , call sayHello Method
new Human().sayHello();
});
// simplify Lambda
method(()‐>new Human().sayHello());
// Use super Keyword instead of parent object
method(()‐>super.sayHello());
}
} But if you use a method reference to call... In the parent class sayHello The method will be better , For example, another subclass Woman :
public class Man extends Human {
@Override
public void sayHello() {
System.out.println(" Hello everyone , I am a Man!");
}
// Define methods method, Parameter passing Greetable Interface
public void method(Greetable g){
g.greet();
}
public void show(){
method(super::sayHello);
}
}In this case , The following two expressions are equivalent :
Lambda expression :
() -> super.sayHello()Method reference :
super::sayHello
8. adopt this Reference member methods
this Represents the current object , If the method to be referenced is the member method in the current class , Then you can use this:: Member method To use method references . The first is a simple functional interface :
@FunctionalInterface
public interface Richable {
void buy();
} Here's a husband Husband class :
public class Husband {
private void marry(Richable lambda) {
lambda.buy();
}
public void beHappy() {
marry(() ‐> System.out.println(" Buy a house "));
}
} Happy way beHappy Called the marriage method marry , The parameters of the latter are functional interfaces Richable , So you need a Lambda expression . But if this Lambda The content of the expression already exists in this class , You can be right Husband Husband class to modify :
public class Husband {
private void buyHouse() {
System.out.println(" Buy a house ");
}
private void marry(Richable lambda) {
lambda.buy();
}
public void beHappy() {
marry(() ‐> this.buyHouse());
}
}If you want to cancel Lambda expression , Replace with method reference , The better way to write it is :
public class Husband {
private void buyHouse() {
System.out.println(" Buy a house ");
}
private void marry(Richable lambda) {
lambda.buy();
}
public void beHappy() {
marry(this::buyHouse);
}
}In this case , The following two expressions are equivalent :
Lambda expression :
() -> this.buyHouse()Method reference :
this::buyHouse
9. Constructor reference for class
Because the name of the constructor is exactly the same as the class name , Not fixed . So constructor references use Class name ::new The format of . The first is a simple Of Person class :
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} Then it is used to create Person Object :
public interface PersonBuilder {
Person buildPerson(String name);
}To use this functional interface , Can pass Lambda expression :
public class Demo09Lambda {
public static void printName(String name, PersonBuilder builder) {
System.out.println(builder.buildPerson(name).getName());
}
public static void main(String[] args) {
printName(" Li-ying zhao ", name ‐> new Person(name));
}
} But by constructor reference , There's a better way to write :
public class Demo10ConstructorRef {
public static void printName(String name, PersonBuilder builder) {
System.out.println(builder.buildPerson(name).getName());
}
public static void main(String[] args) {
printName(" Li-ying zhao ", Person::new);
}
} In this case , The following two expressions are equivalent :
Lambda expression :
name -> new Person(name)Method reference :
Person::new
10. Array constructor reference
An array is Object Subclass object of , So there are also constructors , It's just that the grammar is a little different . If it corresponds to Lambda In the usage scenario of , Need a functional interface :
@FunctionalInterface
public interface ArrayBuilder {
int[] buildArray(int length);
} When applying this interface , Can pass Lambda expression :
public class Demo11ArrayInitRef {
private static int[] initArray(int length, ArrayBuilder builder) {
return builder.buildArray(length);
}
public static void main(String[] args) {
int[] array = initArray(10, length ‐> new int[length]);
}
}But a better way to write it is to use the constructor reference of an array :
public class Demo12ArrayInitRef {
private static int[] initArray(int length, ArrayBuilder builder) {
return builder.buildArray(length);
}
public static void main(String[] args) {
int[] array = initArray(10, int[]::new);
}
} In this case , The following two expressions are equivalent :
Lambda expression : length -> new int[length]
Method reference : int[]::new
边栏推荐
- 有哪些值得学习的 Go 语言开源项目
- SAP S/4HANA New Simplified Data Model (NSDM) 模型介绍
- Top ten cases of "enterprise digital transformation"!
- Swift custom subscript
- 直播软件开发,工具类的自定义弹窗效果
- In the process of emergency response, what is a good way to find files created on a certain date?
- C# Channel 简单实现消息队列的发布、订阅
- 【集训DAY1】Maximum benefit【离散化】【贪心】
- SQL杂谈
- [深入研究4G/5G/6G专题-37]: URLLC-8-《3GPP URLLC相关协议、规范、技术原理深度解读》-2-网络架构、时延分析与URLLC载波部署形态
猜你喜欢

嵌入式开发:提示和技巧——满足实时期限的7个技巧

诺基亚的专利生意首次遭受打击,中国企业已不是那么容易揉捏了

Log in and operate the database with the command line

如何清理你的电子邮件订阅者名单以改善电子邮件营销

【集训DAY4】Sequence transformation【思维】

The logic of archives | archives collection

ncnn 推理框架安装;onnx转ncnn

290 pages 110000 words digital agriculture rural project planning and construction scheme 2022

但斌投资峰会:论资产管理的重要性!

Qt(四)使用代码与UI文件混合开发
随机推荐
[深入研究4G/5G/6G专题-36]: URLLC-7-《3GPP URLLC相关协议、规范、技术原理深度解读》-1-业务场景、演进路线和性能要求
父游标、子游标及共享游标
Logic of archives | holonomic distinction and examples
华为通用卡证识别功能,一键实现多种卡绑定
One article understand go integrate CAPTCHA to realize the function of verification code
Qt(五)元对象特性
记录记录记录
SQL gossip
SAP S/4HANA New Simplified Data Model (NSDM) 模型介绍
谐云课堂 | 敏捷开发流程及项目实战分享
Leecode subarray XOR query
Selenium uses' chromedriver 'executable needs to be in path Error reporting information
【Luogu_P4556】 [Vani有约会]雨天的尾巴 /【模板】线段树合并
How to add PTZ control to the easycvr video retrieval page?
Common methods of golang net network package
docker mysql容器如何开启慢查询日志
开发那些事儿:如何解决RK芯片视频处理编解码耗时很长的问题?
测试开发的六大能力
直播软件开发,工具类的自定义弹窗效果
一文搞懂Go整合captcha实现验证码功能