Java8方法引用

方法引用有助於通過名稱指向方法。方法參考描述使用「::」符號。一種方法參考可以用來指向下列類型的方法。

方法引用實例

使用所選擇的任何編輯器創建下面的java程序C:> JAVA

Java8Tester.java

import java.util.List;
import java.util.ArrayList;

public class Java8Tester {

   public static void main(String args[]) {
      List names = new ArrayList();

      names.add("Mahesh");
      names.add("Suresh");
      names.add("Ramesh");
      names.add("Naresh");
      names.add("Kalpesh");
      // 打印列表list中的所有元素的
      names.forEach(System.out::println);
   }
}

在這裏,我們通過使用System.out:: println方法爲靜態方法引用。

驗證結果

現在運行Java8Tester看到的結果

Mahesh
Suresh
Ramesh
Naresh
Kalpesh
    //引用對像中的方法
    Object :: methodName 

以下是lambda表達式的示例,該表達式僅在整個執行過程中調用一個方法:

    //打印列表中的所有元素
    list.forEach(s -> System.out.println(s)); 

為了使代碼清晰緊湊,在上面的示例中,可以將lambda表達式轉換為方法引用:

//打印列表list中的所有元素的
list.forEach(System.out::println); 

有四種類型的方法參考:

  1. 靜態方法參考。
  2. 特定對象的實例方法引用。
  3. 實例方法對特定類型的任意對象的引用。
  4. 構造函數參考。

為了研究所有這種類型,我們將考慮使用比較器示例進行排序。

1. 引用靜態方法:

如果Lambda表達式類似於:

//如果lambda表達式僅調用類的靜態方法
(args) -> Class.staticMethod(args) 

然後方法參考就像:

    //如果lambda表達式僅調用類的靜態方法的簡寫
   Class::staticMethod  
// This Example shows how one can use 
// Static method reference to sort 
// with custom comparator 
import java.io.*; 
import java.util.*; 

// Object need to be sorted. 
class Person { 
    private String name; 
    private Integer age; 

    // Constructor 
    public Person(String name, 
                int age) 
    { 
        this.name = name; 
        this.age = age; 
    } 

    public Integer getAge() 
    { 
        return age; 
    } 
    public String getName() 
    { 
        return name; 
    } 
} 

public class GFG { 

    // A static method to 
    // compare with name 
    public static int compareByName(Person a, 
                                    Person b) 
    { 
        return a.getName() 
            .compareTo(b.getName()); 
    } 

    // A static method to 
    // compare with age 
    public static int compareByAge(Person a, 
                                Person b) 
    { 
        return a.getAge() 
            .compareTo(b.getAge()); 
    } 

    // Main 
    public static void main(String[] args) 
    { 
        // List of person 
        List<Person> personList 
            = new ArrayList<>(); 
        // Add Elements 
        personList 
            .add(new Person("vicky", 24)); 
        personList 
            .add(new Person("poonam", 25)); 
        personList 
            .add(new Person("sachin", 19)); 

        // Use static method reference to 
        // sort array by name 
        Collections.sort(personList, 
                        GFG::compareByName); 
        System.out.println("Sort by name :"); 
        personList.stream() 
            .map(x -> x.getName()) 
            .forEach(System.out::println); 

        // Use static method reference 
        // to sort array by age 
        Collections.sort(personList, 
                        GFG::compareByAge); 
        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

2. 引用特定對象的實例方法:

如果Lambda表達式類似於:

//如果lambda表達式只是調用ObjectType的默認方法
(obj, args) -> obj.instanceMethod(args) 

然後方法參考就像:

//如果lambda表達式只是調用ObjectType的默認方法,則為簡寫
ObjectType::instanceMethod 
// This Example is same as above but 
// using object method reference to 
// sort with custom comparator 
import java.io.*; 
import java.util.*; 

// Object need to be sorted. 
class Person { 
    private String name; 
    private Integer age; 

    // Constructor 
    public Person(String name, int age) 
    { 
        this.name = name; 
        this.age = age; 
    } 

    public Integer getAge() 
    { 
        return age; 
    } 
    public String getName() 
    { 
        return name; 
    } 
} 

// Comparator class 
class ComparisonProvider { 
    // A method to compare with name 
    public int compareByName(Person a, 
                            Person b) 
    { 
        return a.getName() 
            .compareTo(b.getName()); 
    } 

    // A method to compare with age 
    public int compareByAge(Person a, 
                            Person b) 
    { 
        return a.getAge() 
            .compareTo(b.getAge()); 
    } 
} 

public class GFG { 
    // Main 
    public static void main(String[] args) 
    { 
        // List of person 
        List<Person> personList = new ArrayList<>(); 
        // Add Elements 
        personList.add(new Person("vicky", 24)); 
        personList.add(new Person("poonam", 25)); 
        personList.add(new Person("sachin", 19)); 

        // A comparator class with multiple 
        // comaparator methods 
        ComparisonProvider comparator 
            = new ComparisonProvider(); 

        // Use instance method reference 
        // to sort array by name 
        Collections.sort(personList, 
                        comparator::compareByName); 
        System.out.println("Sort by name :"); 
        personList.stream() 
            .map(x -> x.getName()) 
            .forEach(System.out::println); 

        // Use instance method reference 
        // to sort array by age 
        Collections.sort( 
            personList, 
            comparator::compareByAge); 
        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表達式只是調用對象的默認方法
(args) -> obj.instanceMethod(args) 

然後方法參考就像:

// 如果lambda表達式只是調用對象的默認方法的簡寫
obj::instanceMethod 

例子:

// This Example shows how one can use 
// Instance type method reference 
// to sort with custom comparator 

import java.io.*; 
import java.util.*; 

public class GFG { 
    // Main 
    public static void main(String[] args) 
    { 
        // List of person 
        List<String> personList 
            = new ArrayList<>(); 

        // Add Elements 
        personList.add("vicky"); 
        personList.add("poonam"); 
        personList.add("sachin"); 

        // Method reference to String type 
        Collections.sort( 
            personList, 
            String::compareToIgnoreCase); 
        personList.forEach( 
            System.out::println); 
    } 
} 

4. 構造方法參考:

如果Lambda表達式類似於:

//如果一個lambda表達式只是創建一個對象
(args) -> new ClassName(args) 

然後方法參考就像:

// lambda表達式只是創建對象的簡寫
ClassName::new 
// This Example shows how one 
// can use constructor method reference 

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(); 

        // length is bounded by 7 
        byte[] array = new byte[7]; 
        ran.nextBytes(array); 

        // Asigning Random values 
        // to name and age 
        this.name 
            = ran 
                .ints(97, 122 + 1) 
                .limit(7) 
                .collect(StringBuilder::new, 
                        StringBuilder::appendCodePoint, 
                        StringBuilder::append) 
                .toString(); 
        this.age = age; 
    } 

    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 suppliying 
        // 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

結論:

如上所述,如果lambda表達式僅調用現有方法,則使用方法引用可以使代碼更具可讀性和清晰度。使用Java流時,我們可以使用Java8 Lambda和方法引用做更多的事情。