Search code examples
javareferenceequalspool

Java - Object-Pool with same references


As a simple personal exercise I want to do the following:

  • Create a class, which represent a single integer value
  • No two objects of this class with the same integer value should exist at any moment in time

This is how I approach the problem:

public class MyClass {

   // Static pool
   private static HashSet<MyClass> pool;

   // Integer value each object holds
   private int value;

   static {
     pool = new HashSet<MyClass>();
   }

   // private Constructor
   private MyClass(int value) {
     this.value = value;
   }

   // Static public method to create MyClass objects
   public MyClass create(int value) {
      // Create tmp object with private constructor
      MyClass tmp = new MyClass(value);

      // At this point I want to check, whether an object with the
      // same integer value exists in the HashSet.
      // If this is the case I would like to return a reference to
      // the object in the HashSet (the GC will remove tmp).
      // Otherwise I would like to add tmp to the HashSet and return
      // a reference to tmp.
   }

}

Part of the question is written as part of a comment in the code posted above. I'm curious about the following things. If I don't overwrite equals(Object obj), pool.contains(tmp) will always return false (since the default equals(Object obj) inherited from Object tests for reference. I could overwrite equals(Object obj) to compare the value-fields of the objects, but how would I get the reference out of the HashSet to return it?

Do I need to do anything with hashcode()?


Solution

  • Assuming you're using Java 8, use a Map<Integer, MyClass>:

    private static Map<Integer, MyClass> map = new HashMap<>();
    

    Then, in your method:

    public MyClass create(int value) {
      synchronized (map) {
        return map.computeIfAbsent(value, MyClass::new);
      }
    }