Java 使用“默认”哈希映射调用不同的构造函数

Java 使用“默认”哈希映射调用不同的构造函数,java,constructor,default-constructor,Java,Constructor,Default Constructor,我在MyClass类上运行了很多测试用例,使用它的默认构造函数:MyClass 现在MyClass的需求发生了变化,用户可以提供一个HashMap来指示某些对。现在,MyClass需要至少有一对,如果其中一对为null,则抛出异常 我希望创建另一个默认构造函数,以避免重写所有测试方法,例如: public MyClass() { HashMap<KeyClass, ValueClass> hashMap = HashMap<KeyClass, ValueClass>

我在MyClass类上运行了很多测试用例,使用它的默认构造函数:MyClass

现在MyClass的需求发生了变化,用户可以提供一个HashMap来指示某些对。现在,MyClass需要至少有一对,如果其中一对为null,则抛出异常

我希望创建另一个默认构造函数,以避免重写所有测试方法,例如:

public MyClass() {

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

}

但在我看来,这并不是一种很好的风格,所以我希望你能告诉我这样做的正确方式是什么

您可以内联HashMap创建:

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

但您必须忽略序列id警告,以保持其美观。

您可以内联HashMap创建:

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

但是你必须忽略serial id警告以保持它的美观。

就我个人而言,我会创建一个新的HashMap。。。在这两个构造函数中,不要尝试用新的静态方法包装创建过程。

就我个人而言,我会创建一个新的HashMap。。。在两个构造函数中,不要尝试用新的静态方法包装创建。

以下是我通常使用的解决方案:

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

与@alpian建议的HashMap类子类相比,我更喜欢它,因为它看起来更干净,而且也不会造成违反此处描述的equals方法契约的风险:

以下是我通常使用的解决方案:

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

与@alpian建议的HashMap类的子类化相比,我更喜欢它,因为它看起来更干净,而且也不会造成违反此处描述的equals方法契约的风险:

如果您希望避免创建一个新的匿名HashMap子类,并且只需要一对,并且不想创建一个新的静态方法,您可以这样做:

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

如果希望避免创建新的匿名HashMap子类,并且只需要一对,并且不希望创建新的静态方法,则可以执行以下操作:

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


如果您试图在测试的类中添加测试数据,我的意思是在MyClass中创建一个默认HashMap来测试它,我认为这是一个坏主意。最好是使用HashMap anbd的构造函数从您的测试中提供它。事实上,我在更改之前的其他方法上运行测试,因此它们完全独立于hashmapRight,但是您真的需要在MyClass中使用某种默认HashMap,还是仅仅因为您在测试中遇到了问题?不,我并不真的需要一个默认构造函数,这确实是一个方便性的问题,我当然也很感兴趣,如果100%需要一个默认构造函数,我该如何管理它。最后但并非最不重要的一点是,我可能需要在以后更改更多内容,以便不必过多地打开旧的测试用例。我一直计划提供一个默认构造函数,也可以肯定,不会突然抛出任何异常:我支持reef-如果类的预期使用模式不需要默认构造函数,然后我会反对仅仅为了节省单元测试的工作量而添加一个。假设没有什么可以阻止类的用户调用这个默认构造函数,它可能会给出您不期望的行为?如果您试图在测试的类中添加测试数据,我的意思是在MyClass中创建一个默认HashMap来测试它,我认为这是一个坏主意。最好是使用HashMap anbd的构造函数从您的测试中提供它。事实上,我在更改之前的其他方法上运行测试,因此它们完全独立于hashmapRight,但是您真的需要在MyClass中使用某种默认HashMap,还是仅仅因为您在测试中遇到了问题?不,我并不真的需要一个默认构造函数,这确实是一个方便性的问题,我当然也很感兴趣,如果100%需要一个默认构造函数,我该如何管理它。最后但并非最不重要的一点是,我可能需要在以后更改更多内容,以便不必过多地打开旧的测试用例。我一直计划提供一个默认构造函数,也可以肯定,不会突然抛出任何异常:我支持reef-如果类的预期使用模式不需要默认构造函数,然后我会反对仅仅为了节省单元测试的工作量而添加一个。想必没有什么可以阻止你的类的用户调用这个默认构造函数,它可能会给出你不期望的行为?谢谢!时间一到,我就接受你的回答:不客气,@Peter:当我看到有4个新答案出现时,我通常还在打字;谢谢,太棒了!时间一到,我就接受你的回答:不客气,@Peter:当我看到有4个新答案出现时,我通常还在打字;它是如何打破equals方法的约定的?它不会发生在HashMap中,而是发生在equals方法通过调用.getC检查其他操作数类型的其他类中
lass,这样的问题可能会发生。它是如何打破equals方法的契约的?HashMap不会发生这种情况,但是其他类的equals方法通过调用.getClass检查其他操作数的类型,这样的问题可能会发生。谢谢,这确实可能是更干净的方法,唯一的一点是,阿尔卑斯的方法我可以添加更多的元素,所以它很方便。不过我同意,对于一个元素来说,这可能是最优雅的解决方案。谢谢,这确实可能是更干净的方法,唯一的一点是alpian的方法我可以添加更多元素,所以它很方便。不过我同意,对于一个元素来说,这可能是最优雅的解决方案。