Functional Interfaces in Java 和 Lambda Function 是掌握 Java 中方法引用所需的先決條件。眾所周知,method 是執行某些特定任務並將結果返回給調用者的語句的集合。方法可以執行某些特定任務而不返回任何內容。方法允許我們重用代碼而無需重新輸入代碼。在本文中,我們將了解如何使用方法作為值。
在 Java 8 中,我們可以像使用對象或原始值一樣使用方法,並且可以將它們視為變量。該示例將函數顯示為 java 中的變量:
// This square function is a variable getSquare. Function<Integer, Integer> getSquare = i -> i * i;
SomeFunction(a, b, getSquare); // Pass function as a argument to other function easily
有時,lambda 表達式僅調用現有方法。在這些情況下,通過名稱引用現有方法看起來很清楚。方法引用可以做到這一點,與 lambda 表達式相比,它們很緊湊,easy-to-read。方法引用是僅包含一個方法調用的 lambda 表達式的簡寫語法。這是 a 的一般語法
通用語法:方法參考
A. 引用對象中的方法
Object :: methodName
B. 打印列表中的所有元素
以下是在整個執行過程中僅調用單個方法的 lambda 表達式的示例:
list.forEach(s -> System.out.println(s));
C. 打印列表中所有元素的簡寫
為了使代碼清晰緊湊,在上麵的示例中,可以將 lambda 表達式轉換為方法引用:
list.forEach(System.out::println);
方法引用隻能用於替換 lambda 表達式的單個方法。如果使用 lambda 表達式而不是使用匿名類,並且可以使用方法引用而不是使用單個函數 lambda 表達式來實現相同的目的,則代碼會更加清晰和簡短。一般來說,不必將參數傳遞給方法引用。
下麵的示例是對列表中的元素執行一些操作並添加它們。對元素執行的操作是一個函數參數,調用者可以相應地傳遞。
示例:
public int transformAndAdd(List<Integer> l, Function<Integer, Integer> ops) { int result = 0; for (Integer s : l) result += f.apply(s); return results; } // Operations utility class class OpsUtil { // Method 1 // To half the variable public static Integer doHalf(Integer x) { return x / 2; } // Method 2 // Square up the integer number public static Integer doSquare(Integer x) { return x * x; } ... many more operations... }
上述方法的調用方式如下:
List<Integer> list = new ArrayList<>(); // Add some element to list ... // Using an anonymous class transformAndAdd(list, new Function<Integer, Integer>() { public Integer apply(Integer i) { // The method return OpsUtil.doHalf(i); } }); // Using a lambda expression tranformAndAdd(list, i -> OpsUtil.doHalf(i)); // Using a method reference tranformAndAdd(list, OpsUtil::doHalf);
方法引用的類型
有四種類型方法引用,如下所示:
- 靜態方法參考。
- 特定對象的實例方法引用。
- 特定類型的任意對象的實例方法引用。
- 構造函數參考。
為了研究所有這些類型,我們將考慮使用比較器排序的常見示例,如下所示:
類型 1:引用靜態方法
如果 Lambda 表達式如下:
// If a lambda expression just call a static method of a class
(args) -> Class.staticMethod(args)
那麽方法參考如下:
// Shorthand if a lambda expression just call a static method of a class
Class::staticMethod
例子:
Java
// Java Program to Illustrate How One can use
// Static method reference
// To Sort with Custom Comparator
// Importing required classes
import java.io.*;
import java.util.*;
// Class 1
// Helper class
// Object need to be sorted
class Person {
private String name;
private Integer age;
// Constructor
public Person(String name, int age)
{
// This keyword refers to current instance itself
this.name = name;
this.age = age;
}
// Getter-setters
public Integer getAge() { return age; }
public String getName() { return name; }
}
// Class 2
// Main class
public class GFG {
// Method 1
// Static method to compare with name
public static int compareByName(Person a, Person b)
{
return a.getName().compareTo(b.getName());
}
// Method 2
// Static method to compare with age
public static int compareByAge(Person a, Person b)
{
return a.getAge().compareTo(b.getAge());
}
// Method 3
// Main driver method
public static void main(String[] args)
{
// Creating an empty ArrayList of user-defined type
// List of person
List<Person> personList = new ArrayList<>();
// Adding elements to above List
// using add() method
personList.add(new Person("vicky", 24));
personList.add(new Person("poonam", 25));
personList.add(new Person("sachin", 19));
// Using static method reference to
// sort array by name
Collections.sort(personList, GFG::compareByName);
// Display message only
System.out.println("Sort by name :");
// Using streams over above object of Person type
personList.stream()
.map(x -> x.getName())
.forEach(System.out::println);
// Now using static method reference
// to sort array by age
Collections.sort(personList, GFG::compareByAge);
// Display message only
System.out.println("Sort by age :");
// Using streams over above object of Person type
personList.stream()
.map(x -> x.getName())
.forEach(System.out::println);
}
}
Sort by name : poonam sachin vicky Sort by age : sachin vicky poonam
類型2:引用特定對象的實例方法
如果 Lambda 表達式如下:
// If a lambda expression just call a default method of an object
(args) -> obj.instanceMethod(args)
那麽方法參考如下:
// Shorthand if a lambda expression just call a default method of an object
obj::instanceMethod
例子:
Java
// Java Program to Illustrate How One can use
// Static method reference
// To Sort with Custom Comparator
// But using object method reference
// Importing required classes
import java.io.*;
import java.util.*;
// Class 1
// Helper class
// Object need to be sorted
class Person {
// Attributes of a person
private String name;
private Integer age;
// Constructor
public Person(String name, int age)
{
// This keyword refers to current object itself
this.name = name;
this.age = age;
}
// Getter-setter methods
public Integer getAge() { return age; }
public String getName() { return name; }
}
// Class 2
// Helper class
// Comparator class
class ComparisonProvider {
// Method 1
// To compare with name
public int compareByName(Person a, Person b)
{
return a.getName().compareTo(b.getName());
}
// Method 2
// To compare with age
public int compareByAge(Person a, Person b)
{
return a.getAge().compareTo(b.getAge());
}
}
// Class 3
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an empty ArrayList of user-defined type
// List of person
List<Person> personList = new ArrayList<>();
// Adding elements to above object
// using add() method
personList.add(new Person("vicky", 24));
personList.add(new Person("poonam", 25));
personList.add(new Person("sachin", 19));
// A comparator class with multiple
// comparator methods
ComparisonProvider comparator
= new ComparisonProvider();
// Now using instance method reference
// to sort array by name
Collections.sort(personList,
comparator::compareByName);
// Display message only
System.out.println("Sort by name :");
// Using streams
personList.stream()
.map(x -> x.getName())
.forEach(System.out::println);
// Using instance method reference
// to sort array by age
Collections.sort(personList,
comparator::compareByAge);
// Display message only
System.out.println("Sort by age :");
personList.stream()
.map(x -> x.getName())
.forEach(System.out::println);
}
}
Sort by name : poonam sachin vicky Sort by age : sachin vicky poonam
類型3:對特定類型的任意對象的實例方法的引用
如果 Lambda 表達式如下:
// If a lambda expression just call an instance method of a ObjectType
(obj, args) -> obj.instanceMethod(args)
那麽方法參考如下:
// Shorthand if a lambda expression just call an instance method of a ObjectType
ObjectType::instanceMethod
例子:
Java
// Java Program to Illustrate how One can use
// Instance type method reference to
// sort with custom comparator
// Importing required classes
import java.io.*;
import java.util.*;
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an empty ArrayList of user defined type
// List of person
List<String> personList = new ArrayList<>();
// Adding elements to above object of List
// using add() method
personList.add("vicky");
personList.add("poonam");
personList.add("sachin");
// Method reference to String type
Collections.sort(personList,
String::compareToIgnoreCase);
// Printing the elements(names) on console
personList.forEach(System.out::println);
}
}
poonam sachin vicky
類型4:構造方法參考
如果 Lambda 表達式如下:
// If a lambda expression just create an object
(args) -> new ClassName(args)
那麽方法參考如下:
// Shorthand if a lambda expression just create an object
ClassName::new
例子:
Java
// Java Program to Illustrate How We can Use
// constructor method reference
// Importing required classes
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.function.*;
// Object need to be sorted
class Person {
private String name;
private Integer age;
// Constructor
public Person()
{
Random ran = new Random();
// Assigning a random value
// to name
this.name
= ran
.ints(97, 122 + 1)
.limit(7)
.collect(StringBuilder::new,
StringBuilder::appendCodePoint,
StringBuilder::append)
.toString();
}
public Integer getAge()
{
return age;
}
public String getName()
{
return name;
}
}
public class GFG {
// Get List of objects of given
// length and Supplier
public static <T> List<T>
getObjectList(int length,
Supplier<T> objectSupply)
{
List<T> list = new ArrayList<>();
for (int i = 0; i < length; i++)
list.add(objectSupply.get());
return list;
}
public static void main(String[] args)
{
// Get 10 person by supplying
// person supplier, Supplier is
// created by person constructor
// reference
List<Person> personList
= getObjectList(5, Person::new);
// Print names of personList
personList.stream()
.map(x -> x.getName())
.forEach(System.out::println);
}
}
vzskgmu iupltfx kocsipj lyvhxsp hbdphyv
Conclusion: As mentioned above, if a lambda expression only calls an existing method then using method reference can make code more readable and clear. There are many more things we can do with Java8 Lambda and Method References while using Java streams.
相關用法
- Java Method within用法及代碼示例
- Java Method類 getModifiers()用法及代碼示例
- Java Method類 isVarArgs()用法及代碼示例
- Java Method類 getDeclaringClass()用法及代碼示例
- Java Method類 getAnnotatedReturnType()用法及代碼示例
- Java Method類 getParameterAnnotations()用法及代碼示例
- Java Method類 getDeclaredAnnotations()用法及代碼示例
- Java Method類 getAnnotation()用法及代碼示例
- Java Method類 getParameterCount()用法及代碼示例
- Java Method類 getGenericParameterTypes()用法及代碼示例
- Java Method類 toGenericString()用法及代碼示例
- Java Method類 isBridge()用法及代碼示例
- Java Method類 getParameterTypes()用法及代碼示例
- Java Method類 getReturnType()用法及代碼示例
- Java Method類 isDefault()用法及代碼示例
- Java Method類 getDefaultValue()用法及代碼示例
- Java Method類 hashCode()用法及代碼示例
- Java Method類 getName()用法及代碼示例
- Java Method類 getGenericReturnType()用法及代碼示例
- Java Method類 getGenericExceptionTypes()用法及代碼示例
- Java Method類 getTypeParameters()用法及代碼示例
- Java Method類 getExceptionTypes()用法及代碼示例
- Java Method類 equals()用法及代碼示例
- Java MessageDigest getAlgorithm()用法及代碼示例
- Java MessageDigest getDigestLength()用法及代碼示例
注:本文由純淨天空篩選整理自vickyrathod大神的英文原創作品 Method References in Java with examples。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。