正确的方式来初始化HashMap,并可以HashMap保存不同的值types?
所以我有两个有关Java中的HashMap
的问题:
-
什么是正确的方式来初始化一个
HashMap
? 我认为这可能是最好的在我的情况下使用:HashMap x = new HashMap();
但是Eclipse总是build议我使用:
HashMap<something, something> map = new HashMap();
哪个更好?
-
HashMap
将不同types的对象/数据types保存为值吗? 例如,这样做是否行得通:map.put("one", 1); map.put("two", {1, 2}); map.put("three", "hello");
在第一个
put()
,我想要一个int
作为值,第二个int[]
,第三个string。 在Java中使用HashMap
吗? 另外,将HashMap
作为一个值存储在HashMap
吗?
这真的取决于你需要什么types的安全。 非通用的做法最好是这样做的:
Map x = new HashMap();
请注意x
被input为一个Map
。 这使得未来更改实现(到TreeMap
或LinkedHashMap
)更容易。
您可以使用generics来确保一定的安全级别:
Map<String, Object> x = new HashMap<String, Object>();
在Java 7和更高版本中,你可以做
Map<String, Object> x = new HashMap<>();
上面,虽然更详细,避免了编译器警告。 在这种情况下, HashMap
的内容可以是任何Object
,所以可以是Integer
, int[]
等,这就是你正在做的事情。
如果您仍在使用Java 6, Guava Libraries (虽然很容易做到),但有一个名为newHashMap()
的方法,可以避免在执行new
时复制genericstypes信息。 它从variables声明中推断出这个types(这是Java 7之前的构造函数中没有的Java特性)。
顺便说一下,当你添加一个int或者其他的基元时,Java会自动装箱。 这意味着代码相当于:
x.put("one", Integer.valueOf(1));
你当然可以把一个HashMap
作为一个值在另一个HashMap
,但是我认为如果你recursion地做了这个(就是把HashMap
当作一个值本身)就会出现问题。
这是Java 1.5所做的改变。 你先列出的是旧的方式,其次是新的方式。
通过使用HashMap,你可以做这样的事情:
HashMap<String, Doohickey> ourMap = new HashMap<String, Doohickey>(); .... Doohickey result = ourMap.get("bob");
如果你没有地图上的types,你必须这样做:
Doohickey result = (Doohickey) ourMap.get("bob");
这真的很有用。 它可以帮助你捕捉错误,避免写入各种额外的表演。 这是1.5(和更新)我最喜欢的function之一。
您仍然可以在地图中放置多个东西,只需将其指定为Map,然后就可以将任何对象放在一个string,另一个Map和Integer中,如果您喜欢,也可以放入三个MyObjects。
Eclipsebuild议您声明HashMap的types,因为这会强制某种types的安全。 当然,这听起来像是你试图避免从第二部分的types安全。
如果你想做后者,试着把map声明为HashMap<String,Object>
。
你写的方式等同于
HashMap<Object, Object> map = new HashMap<Object, Object>();
括号内的内容是你与编译器通信什么你将放在HashMap中,以便它可以为你做错误检查。 如果Object,Object是你真正想要的(可能不是),你应该明确地声明它。 一般而言,您应该尽可能使用声明来明确编译器的错误检查。 你所描述的应该可能是这样声明的:
HashMap<String, Object> map = new HashMap<String, Object>();
这样你至less可以声明你的键是string,但是你的值可以是任何东西。 只要记得在退出价值时使用投射。
第二个是使用Java 1.5引入的generics。 它将减less代码中的强制转换次数,并且可以帮助您在编译时而不是运行时捕获错误。 这就是说,这取决于你在编码。 一个快速和肮脏的地图,以保存各种types的一些对象不需要generics。 但是,如果地图所持有的对象都是Object以外的types,那么这可能是值得的。
之前的海报错误地图中的数组。 一个数组实际上是一个对象,所以它是一个有效的值。
Map<String,Object> map = new HashMap<String,Object>(); map.put("one",1); // autoboxed to an object map.put("two", new int[]{1,2} ); // array of ints is an object map.put("three","hello"); // string is an object
另外,由于HashMap是一个对象,它也可以是一个HashMap中的一个值。
HashMap可以将任何对象保存为一个值,即使它是另一个HashMap也是如此。 Eclipsebuild议您声明types,因为这是Collection的推荐做法。 在Java 5下。你可以自由地忽略Eclipse的build议。
在Java 5中,将int(或任何基本types)添加到集合时,它们将被自动装入到Integer(或其他相应types)中。 但要小心,因为有一些捕获使用自动装箱。
Eclipsebuild议你定义generic type
这样你就可以拥有type safety
。 你可以写
Map m = new HashMap();
这不能保证types的安全,但是下面的内容将确保types安全
Map<Object,Object> = new HashMap<Object,Object>();
Object
可以是任何types,如String
, Integer
等
回答你的第二个问题:是的,一个HashMap可以容纳不同types的对象。 这是不是一个好主意取决于你正在努力解决的问题。
这就是说,你的例子将无法正常工作。 该int值不是一个对象。 您必须使用Integer包装类来在HashMap中存储一个int值