2015-11-24 5 views
3

У меня довольно простой вопрос, но пока ничего не найдено.Java - создайте HashMap в перегруженном вызове конструктора

Я пытаюсь создать два класса конструкторов.
Первый конструктор получает 2 строки и один HashMap и инициализирует переменные класса.

public Foo(String a, String b, HashMap<String, String> c) { 
    this.a = a; 
    this.b = b; 
    this.c = c; 
} 

Второй конструктор должен получить только 2 строки и создать «по умолчанию» -HashMap.

Обычно вы просто вызываете this() со значением по умолчанию внутри, но я не смог найти способ сделать это с помощью HashMap.

public Foo(String a, String b) { 
    this(a, b, new HashMap<String, String>().put("x", "y").put("f","g")); 
} 

Eclipse, отмечает ошибку:

Type mismatch: cannot convert from String to HashMap<String,String>

И иначе this() -Call не может быть первым оператором в функции.

public Foo(String a, String b) { 
    HashMap<String, String> c = new HashMap<String, String>(); 
    c.put("x", "y"); 
    c.put("f", "g"); 
    this(a, b, c); 
} 

Любые идеи, как это решить?

Худший случай Мне пришлось дублировать код, но мне было интересно, нет ли лучшего способа.

+2

Ваша ссылка на 'c' все равно будет такой же. вы можете просто использовать 'this (a, b, new HashMap ());' как ваш первый оператор и продолжать работать с 'c'. – SomeJavaGuy

+1

Карта 's put возвращает текущее значение (V). Следовательно, вы получаете TypeMismatch. – amdalal

ответ

4

Нет необходимости создавать локальную переменную c.

Вы можете просто называть это следующим образом.

public Foo(String a, String b) { 
    this(a, b, new HashMap<String, String>()); 
    c.put("x", "y"); 
    c.put("f", "g"); 
} 

С вашего другого конструктором this(String, String, HashMap<String, String>()) назначит новые HashMap в c методы, ссылающихся на c будет также заполнить эту вновь созданный HashMap и присвоит значения по умолчанию, которые ты предоставить ей.

Другим решением может стать создание статического метода и назвать его просто

public static HashMap<String, String> createDefaultHashMap() { 
    HashMap<String, String> c = new HashMap<String, String>(); 
    c.put("x", "y"); 
    c.put("f", "g"); 
    return c; 
} 

public Foo(String a, String b) { 
    this(a, b, Foo.createDefaultHashMap());; 
} 
+0

Спасибо! Вот и все. – John

5

Если эта Карта является постоянной, вы можете сохранить ее как постоянную и использовать ее повторно. Это позволяет избежать воссоздания Карты каждый раз, когда создается новый Foo, но затем он передается по всем Foo.

public class Foo { 

    private static final Map<String, String> DEFAULT = new HashMap<>(); 

    static { 
     DEFAULT.put("x", "y"); 
     DEFAULT.put("f","g"); 
    } 

    public Foo(String a, String b) { 
     this(a, b, DEFAULT); 
    } 

    public Foo(String a, String b, Map<String, String> c) { 
     this.a = a; 
     this.b = b; 
     this.c = c; 
    } 

} 

Вы также можете создать статический метод, возвращающий правильное значение. Обратите внимание, что метод должен быть статическим, потому что вы не можете вызвать метод экземпляра внутри this().

public class Foo { 

    public Foo(String a, String b) { 
     this(a, b, getDefaultMap()); 
    } 

    public Foo(String a, String b, Map<String, String> c) { 
     this.a = a; 
     this.b = b; 
     this.c = c; 
    } 

    private static Map<String, String> getDefaultMap() { 
     Map<String, String> map = new HashMap<>(); 
     map.put("x", "y"); 
     map.put("f", "g"); 
     return map; 
    } 

} 
1

HashMap метод .put возвращает String так что вы передаете String при вызове конструктора 3 аргумента в ваших 2 аргумента конструктора.

0

Вы можете сделать трюк, как это:

public Foo(String a, String b) { 
    this(a, b, new HashMap<String, String>(){ 
     { 
      put("x", "y"); 
      put("f", "g"); 
     } 
    }); 
} 

Это создает анонимный класс, который наследует HashMap и определяет инициализации блока с указанием значений.

+1

Это называется инициализацией с двойной привязкой, но я не уверен, рекомендую ли я ее. – Tunaki

+0

Это не требует другого метода и довольно читается –

+0

Да, но обратите внимание, что он создает анонимный внутренний класс. Подробнее [здесь] (http://stackoverflow.com/q/1958636/1743880). – Tunaki

0

Вы можете работать вокруг «вызова к этому() должен быть первым оператором», добавив статические метод, который создает ваше по умолчанию Map экземпляра:

public Foo(String a, String b) { 
    this(a, b, createDefaultMap()); 
} 

private static Map<String, String> createDefaultMap() { 
    Map<String, String> defaultMap = new HashMap<String, String>(); 
    defaultMap.put("x", "y"); 
    defaultMap.put("f", "g"); 

    return defaultMap; 
} 

Это является обязательным, что createDefaultMap() является статическим, так как вы не можете получить доступ к полуконструированному экземпляру в этот момент.

Смежные вопросы