泛型和 TreeSet

发布于 2024-10-15 11:46:00 字数 421 浏览 2 评论 0原文

使用泛型绝对是我的弱点,并且可以在这方面使用一些帮助。

该项目旨在开发一个简单的订单/库存系统,用于下订单、跟踪物品和​​库存,并记录自项目首次启动以来的所有库存和客户添加/删除。这需要读取和写入文件,我选择了 CSV 格式来解析。有两个文件需要解析,一个用于 Customers,另一个用于 Items

我想使用 TreeSet 来添加/搜索 log N,但我的文件解析遇到一些问题。我不想让两个具有重复代码的类为其对象类型工作,而是希望有一个解析类在执行时接收集合和文件路径,并将文件处理成完整的对象集,这两个对象都有不同的领域和方法。

我想出的唯一解决方案是 TreeSet,但这意味着我必须对结构中访问的每个对象进行装箱,然后取消装箱。

有更简单的方法吗?

Working with Generics is definitely my weak spot, and can use some help with this.

The project is to develop a simple order/inventory system that places orders, keeps track of items and inventories, and keeps a record of all inventory and customer addition/removals since the program first started. This requires reading and writing to a file, and I've picked the CSV format to parse. There are two files to parse, one for Customers and one for Items.

I want to use a TreeSet to make additions/searches log N, but am having some trouble with my file parsing. Rather than have two classes with duplicate code working for their object type, I'd like to have a single parse class taking in the set and file path on execution, and processing the file into a complete set of objects, both of whom have differing fields and methods.

The only solution I've come up with is TreeSet<? extends Object>, but that means that I'll have to box, then unbox each object as its accessed in the structure.

Is there an easier way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别低头,皇冠会掉 2024-10-22 11:46:00

以下是层次结构的示例。

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);

Here's an example of what your hierarchy could look like

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);

Alternatively you could push the generics down to the method level of CVSParser and make it static even:

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


Set<Item> items = CVSParser.parse(new ItemHandler(), itemsFile);
蓝眸 2024-10-22 11:46:00

您是否正在寻找

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;
}

Are you looking for

interface CSVParseableObject {
   // routines
}

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

And then

TreeSet<CSVParseableObject>

In which you parse can use e.g.,

Set<CSVParseableObject> parse(String path) {
    Set<CSVParseableObject> parseableObjects = new TreeSet<CSVParseableObject>();
    File file = new File(path);
    // parse ... 
    return parseableObjects;
}
表情可笑 2024-10-22 11:46:00

这里有一个选项:

设计一个类来表示库存项目,并让该类扩展或(更好)实现您的解析接口。通过这种方式,您可以简单地将 Inventory 对象插入到树中。

例如,TreeSet树 = TreeSet<库存>()
tree.add(库存对象)等

Here is an option:

Design a class to represent an Inventory item, and have that extend or (better) implement your parsing interface. In this way, you can simply insert the Inventory object into your tree.

E.g., TreeSet<Inventory> tree = TreeSet<Inventory>()
tree.add(Inventory Object), etc.

ゃ人海孤独症 2024-10-22 11:46:00

猜猜你确实很困惑。

每个文件代表来自不同对象类型(客户和项目)的数据,因此它们的格式不同,字段也不同。您不能使用相同的代码来解析它们。

我希望有一个解析类在执行时接收集合和文件路径,并将文件处理成完整的对象集,这两个对象都有不同的字段和方法。

您可以有一个类,但您需要不同的代码来读取两种不同的文件类型。事实上,您希望填充通用集合对象,这将避免您以自己的方式处理每种文件类型。泛型只是为了节省一些手动转换的时间,并避免将不需要的对象意外添加到集合中。

您可以在代码中执行类似的操作:

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

您可以使用较少的“自定义代码”方式来完成此操作...也许是嵌入式数据库...但如果这就是您现在希望执行的操作,您将学习新的方法随着时间的流逝,会发生同样的事情。

Guess you are confused indeed.

Each file represents data from a different object type (Customers and Items), so their formats are different, so are their fields. You can't have the same code parse them both.

I'd like to have a single parse class taking in the set and file path on execution, and processing the file into a complete set of objects, both of whom have differing fields and methods.

You can have a single class, but you'll need different code to read the two different file types. It's not the fact that you wish to fill a generic collection object that will avoid you from handling each file type in its own way. Generics is only intended to save you some manual casting and avoiding accidental addition of unwanted objects into collections.

You can do something like this in your code:

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

You could do it with a less "custom-code" way... an embedded database maybe... but if that's how you wish to do now, you'll learn new ways do to the same thing as time passes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文