Search code examples
javagenericstreeset

Generics and TreeSets


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?


Solution

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