1. 程式人生 > ><資料結構與演算法分析>讀書筆記--函式物件

<資料結構與演算法分析>讀書筆記--函式物件

關於函式物件,百度百科對它是這樣定義的:

過載函式呼叫操作符的類,其物件常稱為函式物件(function object),即它們是行為類似函式的物件。又稱仿函式

 

聽起來確實很難懂,通過搜尋我找到一篇部落格,作者對其是這樣的描述:

如果把物件理解成指標的話,也就是說,函式物件其實就是函式指標的概念。

這是該作者通過類比法比較出來的:

我們常說java沒有指標,其實java中的物件引用就是指標,有時候我們說一個物件往往指的就是這個物件的引用,也就是說基本上把物件的引用與物件等同了

 

<資料結構與演算法分析>讀書筆記--利用Java5泛型實現泛型構件

  指出如何編寫泛型演算法。例如泛型方法能夠找出一個數組的最大項。

然而,這種泛型方法有一個重要的侷限:它只對Comparable介面的物件有效,因為它使用compareTo()方法作為所有比較決策的基礎。

在許多情形下,這種處理方式是不可行的。例如:儘管假設Rectangle類實現Comparable介面有些過分,但即使實現了該介面,它所具有的compareTo方法恐怕還不是我們想要的方法。

例如,給定一個2x10的矩形和一個5x5的矩形,哪個是更大的矩形呢?答案恐怕依賴於我們是使用面積還是使用長度來決定。或者,如果我們試圖通過一個開口構造該矩形,那麼或許較大的矩形就是具有較大最小周長的矩形。

 

上述這些情形的解決方案是重寫findMax,使它接受兩個引數:一個是物件的陣列,另一個是比較函式,該函式解釋如何決定兩個物件中哪個大哪個小。實際上,這些物件不再知道如何比較它們自己;這些資訊從陣列的物件中完全去除了。

 

一種將函式作為引數傳遞的獨創方法是注意到物件即包含資料也包含方法,於是我們定義一個沒有資料而只有方法的類,並傳遞類的一個例項。事實上,一個函式通過將其放在一個物件內部而被傳遞。這樣的物件通常叫做函式物件。

 

示例一(顯示函式物件想法的最簡單實現):

package cn.functionObj.example;

import
java.util.Comparator; import cn.pre.example.FindMaxDemo; public class CaseInsensitiveCompare implements Comparator<String> { @Override public int compare(String lhs, String rhs) { return lhs.compareToIgnoreCase(rhs); } public static<AnyType> AnyType findMax(AnyType[] arr,Comparator<? super AnyType> cmp) { int maxIndex = 0; for (int i = 0; i < arr.length; i++) if(cmp.compare(arr[i], arr[maxIndex]) > 0) maxIndex = i; return arr [maxIndex]; } }

 

package cn.functionObj.example;

public class TestProgram {
    public static void main(String[] args) {
        String [] arr = {"ZEBRA","alligator","crocodile"};
        System.out.println(CaseInsensitiveCompare.findMax(arr, new CaseInsensitiveCompare()));
    }
}

 

執行結果輸出:

對上述兩個類程式碼解釋:

findMax的第二個引數是Comparator型別的物件。介面Comparator在java.util指定幷包含一個compare方法。

檢視原始碼中的一小部分可以發現:

package java.util;


@FunctionalInterface
public interface Comparator<T> {
   
    int compare(T o1, T o2);


}

 

實現介面Comparator<AnyType>型別的任何類都必須要有一個叫作compare的方法,該方法有兩個泛型型別(AnyType)的引數並返回一個int型的量,遵守和compareTo相同的一般約定。因此,示例一中對compare的呼叫可以用來比較陣列的項。另外帶有限制的萬用字元用來表示查詢陣列中的最大項,那麼該comparator必須知道如何比較這些項,或者這些項的超型別的那些物件。為了使用這種版本的findMax,findMax通過傳遞一個String陣列以及實現一個comparator<String>的物件而被呼叫。這個物件屬於CaseInsensitiveCompare型別,,它是我們編寫的一個類。

 

程式碼示例已放置Github:https://github.com/youcong1996/The-Data-structures-and-algorithms/tree/master/Introduction