2011-02-01 54 views
0

使用泛型絕對是我的弱點,並可以使用一些幫助。泛型和TreeSets

該項目旨在開發一個簡單的訂單/庫存系統,該系統可以下訂單,跟蹤物品和​​庫存,並記錄自程序首次啓動以來所有庫存和客戶添加/刪除。這需要讀取和寫入文件,並且我選擇了CSV格式進行解析。有兩個文件需要解析,一個用於Customers,另一個用於Items

我想使用TreeSet來添加/搜索日誌N,但我的文件解析遇到了一些麻煩。我不希望有兩個具有重複代碼的類爲它們的對象類型工作,我希望有一個解析類接受執行時的集合和文件路徑,並將該文件處理成一組完整的對象,這兩個對象都有不同領域和方法。

我想出的唯一解決方案是TreeSet<? extends Object>,但這意味着我必須打開盒子,然後將每個對象作爲在結構中訪問的對象取消裝箱。

有沒有更簡單的方法?

+0

在我看來泛型是Java的弱點...... – thkala 2011-02-01 18:49:22

+0

所以,你想要一個可以解析客戶和項目CSV文件的通用解析器類? – Ishtar 2011-02-01 18:55:03

回答

4

這裏是你的層次可能是什麼樣子

class CVSParser<T> { 
    private final RecordHandler<T> handler; 

    public CVSParser<T>(RecordHandler<T> handler) { 
     this.handler = handler; 
    } 

    public Set<T> parse(File f) { 
     Set<T> records = new TreeSet<T>(); 
     for (String line : file) { //I'm paraphrasing here 
      records.add(handler.parse(splitIntoFields(line))); 
     } 
    } 
} 

interface RecordHandler<T> { 
    public T parse(String[] fields); 
} 

class CustomerHandler implements RecordHandler<Customer> { 
    public Customer parse(String[] fields) { 
     return new Customer(fields[0], fields[1]); 
    } 
} 

class ItemHandler implements RecordHandler<Item> { 
    //... 
} 

Set<Item> items = new CVSParser<Item>(new ItemHandler()).parse(itemsFile); 

另外,您可以推動仿製藥下降到CVSParser方法級別,使其靜態甚至一個例子:

class CVSParser { 
    public static <T> Set<T> parse(RecordHandler<T> handler, File f) { 
     //...   
    } 
} 


Set<Item> items = CVSParser.parse(new ItemHandler(), itemsFile); 
2

您是否在尋找

interface CSVParseableObject { 
    // routines 
} 

public class Customers implements CSVParseableObject{} 
public class Items implements CSVParseableObject{} 

然後

TreeSet<CSVParseableObject> 

在您解析可以使用如

Set<CSVParseableObject> parse(String path) { 
    Set<CSVParseableObject> parseableObjects = new TreeSet<CSVParseableObject>(); 
    File file = new File(path); 
    // parse ... 
    return parseableObjects; 
} 
0

這裏有一個選項:

設計一個類代表一個庫存項目,並且擴展或(更好地)實現您的解析接口。通過這種方式,您可以簡單地將Inventory對象插入樹中。

例如,TreeSet<Inventory> tree = TreeSet<Inventory>() tree.add(清單對象)等

0

猜猜你是糊塗確實如此。

每個文件都表示來自不同對象類型(Customers和Items)的數據,因此它們的格式不同,它們的字段也不同。你不能有相同的代碼解析它們。

我想有一個解析類回吐設置和文件路徑執行,文件處理成一套完整的對象,他們兩人有不同的屬性和方法。

你可以有一個類,但是你需要不同的代碼來讀取兩種不同的文件類型。這不是事實,你希望填充一個通用的集合對象,這將避免你以自己的方式處理每個文件類型。泛型僅用於爲您節省一些手動投射,並避免意外將不需要的對象添加到集合中。

你可以做這樣的事情在你的代碼:

class MyParser { 
    public Set<Customer> readCustomersFile(String path) {...} 
    public Set<Item> readItemsFile(String path) {...} 
} 

你可以用更少的「自定義代碼」的方式...也許一個嵌入式數據庫做...但如果這就是你希望現在要做,你會學到新的方式做到與時間流逝同樣的事情。