2011-02-01 50 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) {...} 
} 

你可以用更少的“自定义代码”的方式...也许一个嵌入式数据库做...但如果这就是你希望现在要做,你会学到新的方式做到与时间流逝同样的事情。