Question

I had a lot of testcases running on the class MyClass, using it's default constructor: MyClass().

Now the requirements of MyClass changed and the user can provide a HashMap to indicate some pairs . Now a MyClass needs to have at least one pair and throws exceptions if one of those is null.

I was hoping to create another default constructor to avoid having to rewrite all the test methods something like:

public MyClass() {

  HashMap<KeyClass, ValueClass> hashMap = HashMap<KeyClass, ValueClass>();
  hashMap.put(KeyClass.someValue, new ValueClass());
  this(hashMap);

}

Now this doesn't work, because i have to call the other constructor first, so i thought of writing some method

private static HashMap<KeyClass, ValueClass> getDefaultHashmap();

and using it to call the other constructor like this:

public MyClass() {

  this(MyClass.getDefaultHashmap());

}

But this seemed to me as not really good style, so i was hoping you could tell me what the right way to do something like this is!

Was it helpful?

Solution

You could inline the HashMap creation:

public MyClass() {
    this(new HashMap<KeyClass, ValueClass>() {{
        put(KeyClass.someValue, new ValueClass());
    }});
}

But you'd have to ignore the serial-id warning to keep it "pretty".

OTHER TIPS

Personally, I would go with creating a new HashMap(...) in both constructors, and not try to wrap the creation in a new static method.

Here's the solution that I typically use:

public MyClass {

  private static Map<KeyClass, ValueClass> newMap() {
     Map<KeyClass, ValueClass> result = new HashMap<KeyClass, ValueClass>();
     result.put(KeyClass.someValue, new ValueClass());
     return result; 
  }

  public MyClass() {
     this(newMap());
  }

  public MyClass(Map<KeyClass, ValueClass> m) { ... }
}

I prefer it over subclassing the HashMap-class (as suggested by @alpian) - Seems cleaner, and also does not create the risk of breaking the contract of the equals() method (described here: http://c2.com/cgi/wiki?DoubleBraceInitialization)

If you want to avoid creating a new anonymous HashMap subclass, and only need one pair, and don't want to make a new static method, you could do this:

public MyClass() {
    this(new HashMap<KeyClass, ValueClass>(
        Collections.singletonMap(KeyClass.someValue, new ValueClass())));
}

If your other constructor takes a Map and copies it, you may not even need to crate the HashMap

public MyClass() {
    this(Collections.singletonMap(KeyClass.someValue, new ValueClass()));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top