Вызов другого конструктора с HashMap «по умолчанию» - PullRequest
1 голос
/ 28 апреля 2011

У меня было много тестовых сценариев, работающих на классе MyClass, используя конструктор по умолчанию: MyClass ().

Теперь требования MyClass изменились, и пользователь может предоставить HashMap для указания некоторых пар. Теперь MyClass должен иметь хотя бы одну пару и генерировать исключения, если один из них равен нулю.

Я надеялся создать еще один конструктор по умолчанию, чтобы избежать необходимости переписывать все методы тестирования, например:

public MyClass() {

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

}

Теперь это не работает, потому что сначала мне нужно вызвать другой конструктор, поэтому я подумал о написании какого-то метода

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

и использовать его для вызова другого конструктора следующим образом:

public MyClass() {

  this(MyClass.getDefaultHashmap());

}

Но мне показалось, что это не очень хороший стиль, поэтому я надеялся, что вы скажете мне, каков правильный способ сделать что-то подобное!

Ответы [ 4 ]

3 голосов
/ 28 апреля 2011

Вы можете встроить создание HashMap:

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

Но вы должны игнорировать предупреждение о серийном идентификаторе, чтобы оно было "красивым".

1 голос
/ 28 апреля 2011

Если вы хотите избежать создания нового анонимного подкласса HashMap, и вам нужна только одна пара, и вы не хотите создавать новый статический метод, вы можете сделать это:

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

Если ваш другой конструктор возьмет карту и скопирует ее, вам может даже не понадобиться создать хэш-карту

public MyClass() {
    this(Collections.singletonMap(KeyClass.someValue, new ValueClass()));
}
1 голос
/ 28 апреля 2011

Вот решение, которое я обычно использую:

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) { ... }
}

Я предпочитаю это, чем подклассифицировать класс HashMap (как предложено @alpian) - Кажется чище, а также не создает рискразрыв контракта метода equals () (описанного здесь: http://c2.com/cgi/wiki?DoubleBraceInitialization)

1 голос
/ 28 апреля 2011

Лично я бы пошел с созданием new HashMap(...) в обоих конструкторах, а не пытался обернуть создание новым статическим методом.

...