我正在做一个将分隔文件读入列并显示它们的小项目。现在我想要一个基本上是HashMap的包装类的列类,但是有一个问题,在调用Columns构造函数之前我不知道第二个通用数据类型。构造函数采用带有数据类型参数的枚举,如下所示:
private enum DataTypes{
NONE, INTEGER, STRING, DATE
}
我想到的是将Column类字段创建为Collection,然后我可以在调用构造函数时初始化它,如下所示:
private class Column {
Collection values;
public Column(DataTypes type){
determineType(type);
}
private void determineType(DataTypes type){
switch(type){
case NONE: this.values = (Collection) new HashMap<Integer, StringBuilder>();
break;
case INTEGER: this.values = (Collection) new HashMap<Integer, Integer>();
break;
case STRING: this.values = (Collection) new HashMap<Integer, StringBuilder>();
break;
case DATE: this.values = (Collection) new HashMap<Integer, Date>();
break;
}
}
}
我的问题是为什么我必须将它转换为集合类型(因为eclipse强迫我)并且它是否意味着我不能使用任何HashMap方法?
对于这样的情况,还有更好的方法或设计模式,还有什么可以改进?有没有什么可以在以后的apraoch出错,例如添加一个值,因为我觉得我需要为每个数据类型添加一个重载函数来添加一个值。
很抱歉这么长的问题清单,但我对实际项目和设计的经验很少,需要一个小小的&#34;指导。 (大学项目很小,有变量,如a,b,c,x,y等)
感谢:)
修改
经过一整天的搜索并询问这个写得非常糟糕的问题,我发现策略设计模式是我需要的,我稍后会发布代码。
答案 0 :(得分:1)
HashMap不会扩展Collection。因此,您无法将HashMap分配给Collection类型的变量。
Eclipse不会强迫你施放。您选择接受其建议编译代码的方式之一,但这并不意味着代码是正确的。它将在运行时失败,因为HashMap不是Collection。
我很难理解这个专栏应该代表什么。什么是HashMap的键和值?而且,如果您真正想要的不是HashMap,而是Collection,那么Collection的价值是什么?
在任何情况下,由于您要存储在Collection / Map中的所有类型都有一个祖先类(Object
),因此您应该将其用作Collection / Map的类型。你也应该存储StringBuilder。改为使用String。
答案 1 :(得分:0)
您可以使用通配符运算符声明HashMap。
private class Column {
HashMap<?,?> values;
然后你可以正常启动Map
case INTEGER: this.values = new HashMap<Integer, Integer>();
唯一的问题是,每当你把HashMap放到HashMap<Integer, Integer>
时,你都必须将它投射到{{1}}。
答案 2 :(得分:0)
HashMap
不是集合,也不是继承自Collection
HashMap
的类定义是:
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
因此,HashMap
是Map
并实施Map
界面,而不是Collection
因为所有的case语句都在实例化HashMap
,所以将值的声明更改为Map
而不是`Collection:
Map values;
此外,由于您的所有case语句都将HashMap
声明为键Integer
,但值为变量类型,因此您可以相应地声明值Map
。
Map<Integer, ?> values;
Eclipse建议您将HashMap
强制转换为Collection
的原因是因为地图不是Collection
的后代,因此满足编译器的唯一方法是投射它们,这仍然会导致运行时错误,因为它们不是集合。
通过对值声明进行更改以键入Map
,您不仅不再需要强制转换,还会消除运行时错误。