这个问题是在 MS 面试中问我的。我想知道这段代码中的确切设计问题。代码已经给出,需要找到设计问题。
我有 MyHashMap 类,它扩展了 java HashMap 类。在 MyHashMap 类中,我必须保留一些员工信息。此 map 中的键将为 firstName+lastName+Address 。
public MyHashMap extends HashMap<Object, Object> {
//some member variables
//
public void put(String firstName, String lastName, String Address, Object obj) {
String key = firstName + lastName+ Address;
put(key, obj);
}
public Object get(String firstName, String lastName, String Address) {
String key = firstName + lastName+ Address;
return get(key);
}
public void remove(Strig key) {
put(key, "");
}
//some more methods
}
这个设计有什么问题?我应该继承 HashMap 还是应该声明 HashMap 作为这个类的成员变量?或者我应该实现 hashCode/equals 方法吗?
最佳答案
有很多问题,但我能看到的最大问题是您使用连接的 String
作为键。下面两个调用是不同的,但是是等价的:
final MyHashMap map = new MyHashMap();
map.put("foo", "", "baz", new Object());
map.put("", "foo", "baz", new Object()); // Overwrites the previous call
还有一个问题是,您将键类型声明为 Object
,但始终使用 String
,因此没有利用随之而来的类型安全性与泛型。例如,如果您想遍历 Map
的 keySet
,则必须将每个 Set
条目转换为 String
,但您无法确定是否有人滥用您的 Map
,例如使用 Integer
键。
就我个人而言,除非您有充分的理由不这样做,否则我赞成组合而不是继承。在您的情况下,MyHashMap
正在重载put
、get
的标准Map
方法和删除
,但不覆盖它们中的任何一个。你应该继承一个类来改变它的行为,但是你的实现并没有这样做,所以组合是一个明确的选择。
举个例子,重载而不是覆盖意味着如果你做出以下声明:
Map<Object, Object> map = new MyHashMap();
没有您声明的方法将可用。正如其他一些答案所建议的那样,最好使用由 firstName、lastName 和 address 组成的对象作为映射键,但您必须记住实现 equals
和 hashCode
,否则您的值将无法从 HashMap
中检索。
关于java - 这个设计有什么问题?覆盖或重载 java.util.HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2279907/