2008-12-26 52 views
0

我有一個名爲DataSet的類,具有各種構造函數,每個構造函數指定不同類型的變量。它看起來有點像這樣:Java:與泛型和收集類型檢測問題

public class DataSet 
{ 
    private HashSet Data; 


    public DataSet(DataObject obj) 
    { 
     Data = new <DataObject>HashSet(); 
     Data.add(obj); 
    } 

    public DataSet(ObjectRelationship rel) 
    { 
     Data = new <ObjectRelationship>HashSet(); 
     Data.add(rel); 
    } 
    // etc. 

注:我還沒有得到測試的代碼由於不完整的部分(這我建立現在)。

在我目前正在構建的函數getDataObjects()中,我需要返回此集合表示的所有DataObject對象。對於初始化類的HashSet的構造函數,Data的類型不是DataObject(如上面的ObjectRelationship),那裏顯然不會存儲任何DataObjects。在這種情況下,我需要能夠檢測到HashSet'Data'啓動的類型(比如,說明是否'ObjectRelationship',我的意思是)。我該怎麼做呢?



TL;博士:如何判斷一個集合(在這種情況下,一個HashSet)用在我的代碼發起的(就像一個「如果」或「開關」語句類型或者其他的東西)?

+0

不使用泛型會導致完全相同的問題。 – Loki 2008-12-26 14:57:49

+0

看來你正在實施某種收藏。也許你可以學習其他集合類的源代碼來了解如何實現你的目標? – Loki 2008-12-26 16:11:11

+0

我只是包裝HashSet來做一些特定的事情。這不是一種真正的新型收藏,但我想我可以做到這一點。儘管如此,它的底層功能根據所提供的數據類型而有所不同。我也只使用了一些特定的類型。 – 2008-12-26 16:15:50

回答

1

您可以從集合中獲取對象並驗證其類型。

或者你可以有多組來包含不同類型。

或者你可以有一個Class類型的實例變量作爲一個鑑別器作爲一個實例變量。

或者您可以使用最後一種技術爲HashSet創建代理對象。

0

這個類爲CachedRowSet提供了什麼?

對不起,我不認爲這是一個很好的抽象。如果我是你的團隊的成員,我不會使用它。

你的語法對我來說也不正確。 IntelliJ同意我的觀點:它不會編譯。

這並不:

import java.util.HashSet; 
import java.util.Set; 
import java.util.Arrays; 

public class DataSet 
{ 
    private Set<DataObject> data; 


    public DataSet(DataObject obj) 
    { 
     this.data = new HashSet<DataObject>(); 
     data.add(obj); 
    } 

    public DataSet(DataObject[] objs) 
    { 
     data = new HashSet<DataObject>(); 
     data.addAll(Arrays.asList(objs)); 
    } 
    // etc. 
} 

仍然是一個貧窮的抽象。重新考慮它。

+0

所以你說我不應該初始化多個類型? – 2008-12-26 15:02:46

+0

對於初學者來說,是的。我也在說整個班級都對我感覺不對。 – duffymo 2008-12-26 15:03:57

0

您可以將屬性添加到您的數據集類(枚舉值,布爾值或類型),該屬性指定用於初始化哈希集的類型。

在相應的構造函數中設置屬性。這允許您繞過從集合中獲取元素來檢查其類型。

僞代碼:

public class DataSet 
{ 
private HashSet Data; 
private Type _iw = null; 
public Type InitializedWith { return _iw; } 

public DataSet(DataObject) 
{ 
... 
_iw = typeof(DataObject); 
} 

public DataSet(ObjectRelationship) 
{ 
... 
_iw = typeof(ObjectRelationship) 
} 
4

聽起來像是你想整個類類屬模板參數添加到聲明的類,並使用該模板參數類型定義你的HashSet和檢索功能。

我是。此刻淨傢伙,雖然如此,我不能給你的Java語法,但使用C#語法它會是這個樣子:

public class DataSet<T> 
{ 
    private Set<T> Data; 

    public DataSet(T obj) 
    { 
     Data = new HashSet<T>(); 
     Data.add(obj); 
    } 

    public Iterator<T> getDataObjects() 
    { 
     return Data.iterator; 
    } 
} 
0

我要跟着duffymo的建議,只是使用更好的抽象。我打算爲每個計劃使用的特定類型(每個實現一個通用接口)創建多個類,以便我可以繞過這個愚蠢的問題。

在創建每個正確類型的DataSet對象的過程中,它會增加一點點的開銷,但我想這就是它的過程。

1

你可以使用地圖設定的

HashMap <Class<?>, HashSet<Object>> data; 
HashSet temp = data.get(DataObject.class); 
if(temp == null) 
{ 
    temp = new HashSet(); 
    data.put(DataObject.class, temp); 
} 
temp.add(obj); 

然後你會得到兩全其美。

0

我不知道什麼DataObject給你一個對象。

我認爲針對您問題的面向對象方法會使用反映您感興趣的域名(例如發票,客戶等)的類。持久層會隱藏持久性細節。

做到這一點的常用方法是使用數據訪問對象,這可能是這樣的在Java中:

public interface GenericDao<T> 
{ 
    T find(Serializable id); 
    List<T> find(); 
    void save(T obj); 
    void update(T obj); 
    void delete(T obj); 
} 

現在你要處理的對象,而不是東西,嫌關係數據庫。所有的CRUD細節都隱藏在DAO界面後面。

1

聽起來像你的設計需要重新思考。

此外,要明確泛型;您無法在運行時訪問該類型。類型參數僅用於編譯時檢查,並且在運行時完全消失(類型擦除)。