allocating entity identifier

doggz
doggz used Ask the Experts™
on
I have entities which are created and destroyed. each entity has an identifier (int). for now my allocation is simply an incremented counter. I want to improve allocation by reusing the identifiers of destroyed entities rather than incrementing when possible. what is the best way to implement that (in terms of both memory and performance)? one problem I have is that when I reach max int I don't even know how to allocate the next id.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Hi,
i understand that your class is something like this:

class MyClass {
  int id; // sould be unique for each instance

  public MyClass (<arguments>) {
     ...
  }
  ...
}

one option is to use a factory :
class MyClassFactory {
 
  static Vector vDeletedIds = new Vector();
  static int intMaxId = 0;
 
  public static MyClass createInstance(< arguments >) {
     MyClass newInstance = new MyClass(< arguments >);
     newInstance.setID(this.getNextID());
     return newInstance;
  }
 
  public static void destroyInstance(MyClass instance) {
     int id = instance.getID();
     vDeletedIds.add(new Integer(id));
     instance.destroy();
  }
 
  protected static int getNextID() {
    if (vDeletedIds.isEmpty())
      return (++intMaxId);
    else
      return ((Integer)vDeletedIds.firstElement()).intValue();
  }
 
} // MyClassFactory


note:
1. MyClass should implements getID() and setID() methos.
2. uses of the factory in you code:
...
MyClass myClass0 = MyClassFactory.createInstance(); // instead of: new MyClass();
...
MyClassFactory.destroyInstance(myClass0); // instead of myClass0.destroy();
...

-gkern
oops,
the creation method should be:
public static MyClass createInstance(< arguments >) {
    MyClass newInstance = new MyClass(< arguments >);
    newInstance.setID(MyClassFactory.getNextID()); // and not with a reference to "this"
    return newInstance;
 }

-gkern
Another option is this:
class MyClass {

  static Vector vDeletedIds = new Vector();
  static int intMaxId = 0;

  private int id;

  public MyClass() {
    this.id = MyClass.getId();
    // statement
    // for debug: System.out.println("Create " + id);
  }

  private static int getId() {
    if (vDeletedIds.isEmpty())
      return (++intMaxId);
    else
      return ((Integer)vDeletedIds.remove(0)).intValue();
  }

  protected void finalize() throws Throwable {
     vDeletedIds.add(new Integer(id));
     // for debug: System.out.println("Destroy " + id);
     super.finalize();
  }

}

note that in this case you don't have to destroy the class objects yourself - they will be destroyed automatically by the GC.
BUT you depend on GC cycles to collect your objects (you can recommend for memory collection by using System.gc() method)
-gkern

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial