简体   繁体   中英

Code reuse without generics

Say that I need to create 3 linked lists one for int, one for Strings and one for a different type of custom object. If I was using generics it would be easy to do this just by creating one linked list but is there a way to avoid writing the same repetetive code 3 times if I was not using generics?

If you use Integer instead of int , then yes. In this case, all three objects are subclasses of Object so your Linked List class could just deal with Object s.

The code would look, roughly, like:

class MyLinkedList{
    public void add(Object){...}
    public Object remove(Object){...}
    ...
}

Before the introduction of generics in Java 1.5 the Collections all used the type Object, so you would have a linked list of Objects. You then had to make sure yourself that you were adding, retrieving and casting the right types.

I don't see any reason why you shouldn't or wouldn't use generics since using Java 1.4 is hardly necessary or recommended anymore.

您不能对ints vs Strings使用相同的代码,但是假设您的意思是Integers,则必须创建一个存储java.lang.Objects的LinkedList,顺便说一句,这是基于通用的LinkedLists所做的。

You can abstract out the type that the linked list handles into your own type, say StringOrIntOrCustom , that has one of each type, and a flag that specifies which one is the valid one to use. However, you'd need to do a lot of checking to make sure you're not doing an operation that a type does not support whenever you use this data type.

You could do it with out generics, but you would have no compile time type safety checking and you will have to add all the type casting manually.

But then again you will essentially doing what the compiler does when you use generics. Now it's just error prone and manual.

Yes, you can do this, and it's not that hard.

abstract class ListNode {
   public ListNode next_;
};

interface ListNodeFactory {
   public ListNode createListNode();
}

You then create a List class the manipulates ListNode objects. It will have a function it calls to create a new ListNode when it needs one. The add method would take a ListNodeFactory argument. I would suggest most of the methods be protected because no client that's not a derived class is likely to use it.

The you create a derived class from List for each type. You will have to wrap each method with one that takes the type you want. You will also have to create a ListNodeFactory implementation that creates new list nodes with the appropriate type in them. It will also have to cast the ListNode objects it gets out from traversals or removals to the appropriate types in order to get at the data. Here is an example:

class IntListNode extends ListNode {
   public int data_;
   public IntListNode(int x) {
      data_ = x;
   }
}

class IntListNodeFactory implements ListNodeFactory {
   IntListNodeFactory() {
       nextdataset_ = false;
   }
   IntListNodeFactory(int x) {
       nextdataset_ = true;
       data_ = x;
   }
   void setNextData(int x) {
       nextdataset_ = true;
       nextdata_ = x;
   }
   public ListNode createListNode() {
       if (!nextdataset_) {
          throw Exception("Tried to create a node with no data!");
       } else {
          ListNode result = new IntListNode(data_);
          nextdataset_ = false;
          return result;
       }
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM