在“filter collections”中,David Rappoport 講述了一個過濾集合對象的簡單方法。在本文中,他擴展了自己的思想,並展示了怎樣實現,如同用sql的select處理關系數據庫中的表一樣,處理對象數組或集合。他描述了用於選擇,過濾,排序隊形數組或集合的通用機制。通過這種機制,可以在Java的對象數組或集合上實現sql的select函數功能。
假設你希望以表格的形式,如行列的形式,顯示數組或集合中的數據,並且希望可以選擇顯示的屬性。另外,你還希望只顯示滿足一定條件的數據子集,希望用自定義先後順序的的排序標准對數據排序。
這種類型的功能是sql的select函數提供的:在sql語句中,可以定義數據源(通過from指定);可以定義返回的屬性(通過在select後面指定返回列);可以添加條件(where子句);並且可以定義數據顯示的順序(order by子句)。
本文講述了一些使你能把這些函數使用在任何類型的對象數組和集合上的類和接口。為了實現這些函數功能,機制描述使用了一些設計模式。本文提出的方法有一下一些好處:
1。通過本文的代碼(可以下載。。。),你可以在不影響原始數據的前提下,以不同的方式顯示數據。
2。排序,過濾和選擇制定的屬性十分簡單,並且結果能很快得到。
3。通過這些類和接口,你可以獨立的考慮select語句的各部分,從而可以產生純淨,可復用,可擴展的代碼。
但是,你可能也會猜到,機制使用的是通用接口,如果你沒有很好的理解它,可能會濫用它。
機制的類和接口
下面的列表給出了我們需要的類和接口的簡短說明。後文中,你將看到他們怎麼協作,實現設計的功能。每一個類和接口都非常簡單,只含有一個到兩個函數。
1.接口Invoker包含唯一一個函數:public boolean invoke(Object o)。通過這個接口,可以封裝函數調用並返回函數結果。後文你將看到他是怎樣使用的。
2.接口Condition也只包含一個函數:public boolean passes(Object o)。使用這個函數,可以檢測任意類是否滿足任意類型的條件,並返回true或false。同樣,你也將在後文中看到本接口的使用。
3.類SelectStatement代表整個select語句,包含select,from,where和order by等子句。
4.類SelectInstruction表示select子句中的一個單一部分,選定列並指定顯示時該列的名字。一個完整的select子句用一個SelectInstruction對象數組表示。
5.類OrderInstruction代表order by子句的一個單一部分,整個order by子句由一個OrderInstruction對象數組構成。
6.類Executor執行包含了整個執行邏輯的SelectStatement。
7.類ResultTable代表執行SelectStatement後返回的結果集。它用Object[][]的形式組織結果數據,從而可以容易的轉換和顯示數據。
下面將講述這些類和接口時怎樣協作的。類圖顯示了它們之間的關聯。
一個SelectStatement含有一個對象集合或數組(因為集合和數組都只包含統一類型的對象,所以對象的類型沒有關系);一個SelectInstruction對象數組;一個Condition對象數組;和一個OrderInstruction對象數組。然後把SelectStatement對象傳入Excuter對象,在那裡執行這個statement並返回一個ResultTable。
接下來的問題是,SelectInstruction,Condition,OrderInstruction和ResultTable,這些類都是做什麼的?我們為什麼需要他們?首先,不要一下全看他們,這可能會使你迷惑。一個一個的看,每一個類都是易於理解和使用的。
每一個SelectInstruction代表你希望在結果集中出現的一個列(或者對象的一個屬性)。你為他定義一個名字和Invoker。名字將作為列標題出現,Invoker將在集合中的每一個對象上觸發。在某個對象上觸發後,Invoker在對應列中返回該對象的對應屬性。這項函數功能組成了select子句,在這個子句中,可以定義顯示的屬性,並用as定義列名(如select speed as Max_speed)。注意:你也可以只有一個SelectInstruction,其中的列名串為*。在這種情況下,類中的所有getter()方法都被invoker包覆,其結果都出現在ResultSet中。
每一個Condition代表一個條件,源數據集合中每一個對象都需滿足此條件。這個類對應於where子句,通過它可以通過給定的條件排除任意數目的行。注意:如果想要顯示全部對象,只需傳入空的Condintion[]即可。
每一個OrderInstruction代表一個怎樣排序數據的規則,它由一個Invoker和一個Comparator組成。Invoker的invoke(Object o)方法(作用於對象集合中的一個對象時)會返回一個結果,並於作用於集合中其他對象返回的結果進行比較,從而決定結果數據的排序位置。Comparator(如果實現了)比較兩個對象在invoke作用下返回的結果。如果comparator沒有實現,結果將基於它們各自的compareTo(Object o)方法(假定他們都實現了Java.lang,Comparatable)進行比較。
數組中的OrderInstruction之間的順序也非常重要:OrderInstruction對象在數組中出現的越早,它的優先級就越高。這就是說,可以通過應用第一各OrderInstruction,忽略後面的OrderInstruction對象,決定優先級。OrderInstruction類對應於select語句中的order by子句。注意:如果你並不需要對結果進行排序,只需簡單的傳入空
[1] [2] [3] [4] 下一頁