Ash*_*ish 5 java collections programming-languages
这个问题在MS面试时被问到了.我想知道这段代码中的确切设计问题.已经提供了代码,需要找到设计问题.
我有类MyHashMap,它扩展了Java HashMap类.在MyHashMap课程中,我必须保留一些员工的信息.此映射中的键将是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
}
Run Code Online (Sandbox Code Playgroud)
这个设计有什么问题?我应该将HashMap子类化还是应该将HashMap声明为此类的成员变量?或者我应该实现hashCode/equals方法?
Dav*_*ant 13
有很多问题,但最大的问题是我可以看到你使用连接String作为键.以下两个调用是不同的,但相当于:
final MyHashMap map = new MyHashMap();
map.put("foo", "", "baz", new Object());
map.put("", "foo", "baz", new Object()); // Overwrites the previous call
Run Code Online (Sandbox Code Playgroud)
还有,你声明的主要类型作为一个问题Object,但总是用String,因此没有采取随泛型类型安全的优势.例如,如果你想循环遍历keySet你的Map,你必须将每个Set条目转换为a String,但你不能确定有人没有Map使用Integer密钥滥用你,例如.
就个人而言,除非你有充分的理由不这样做,否则我会赞成合成而非继承.在你的情况下,MyHashMap被超载标准Map的方法put,get并且remove,而不是覆盖它们.您应该从类继承以更改其行为,但您的实现不会这样做,因此组合是一个明确的选择.
作为一个例子,重载而不是覆盖意味着如果你做出以下声明:
Map<Object, Object> map = new MyHashMap();
Run Code Online (Sandbox Code Playgroud)
没有任何声明的方法可用.所推荐的一些其他的答案,这将是更好的使用名字,姓氏组成的对象和地址作为地图的关键,但你必须记住落实equals和hashCode,否则你的价值观会不会是从可回收HashMap.
这种设计有什么问题主要是声称是a HashMap<Oject, Object>,但实际上并非如此.重载方法"替换" Map方法,但仍然可以访问 - 现在您应该以与Map接口不兼容的方式使用类,并忽略(在技术上可能)兼容的方式来使用它.
执行此操作的最佳方法是创建一个EmployeeData具有名称和地址字段的类,hashCode()以及equals()基于这些字段的方法(或者更好的是,唯一的ID字段).那么你不需要一个非标准的Map子类 - 你可以简单地使用一个HashMap<EmployeeData, Object>.实际上,值类型应该更具体Object.
| 归档时间: |
|
| 查看次数: |
1590 次 |
| 最近记录: |