Java中的方法引用和示例
Java中的函数式接口和 Lambda函数是掌握Java中的方法引用所需的先决条件。众所周知,方法是执行某些特定任务并将结果返回给调用者的语句的集合。方法可以执行某些特定任务而不返回任何内容。方法允许我们在不重新键入代码的情况下重用代码。在本文中,我们将了解如何将方法用作值。
在Java 8 中,我们可以像使用对象或原始值一样使用方法,并且可以将它们视为变量。该示例将函数显示为Java中的变量:
// This square function is a variable getSquare.
Function getSquare = i -> i * i;
SomeFunction(a, b, getSquare);
// Pass function as a argument to other function easily
有时,lambda 表达式仅调用现有方法。在这些情况下,通过名称引用现有方法看起来很清楚。方法引用可以做到这一点,与 lambda 表达式相比,它们紧凑、易于阅读。方法引用是仅包含一个方法调用的 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 l,
Function 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 list = new ArrayList<>();
// Add some element to list
...
// Using an anonymous class
transformAndAdd(list, new Function() {
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 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);
}
}
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 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);
}
}
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 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);
}
}
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 List
getObjectList(int length,
Supplier objectSupply)
{
List 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 personList
= getObjectList(5, Person::new);
// Print names of personList
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 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 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 List
getObjectList(int length,
Supplier objectSupply)
{
List 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 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.