正确的方式来初始化HashMap,并可以HashMap保存不同的值types?

所以我有两个有关Java中的HashMap的问题:

  1. 什么是正确的方式来初始化一个HashMap ? 我认为这可能是最好的在我的情况下使用:

     HashMap x = new HashMap(); 

    但是Eclipse总是build议我使用:

     HashMap<something, something> map = new HashMap(); 

    哪个更好?

  2. 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 。 这使得未来更改实现(到TreeMapLinkedHashMap )更容易。

您可以使用generics来确保一定的安全级别:

 Map<String, Object> x = new HashMap<String, Object>(); 

在Java 7和更高版本中,你可以做

 Map<String, Object> x = new HashMap<>(); 

上面,虽然更详细,避免了编译器警告。 在这种情况下, HashMap的内容可以是任何Object ,所以可以是Integerint[]等,这就是你正在做的事情。

如果您仍在使用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,如StringInteger

回答你的第二个问题:是的,一个HashMap可以容纳不同types的对象。 这是不是一个好主意取决于你正在努力解决的问题。

这就是说,你的例子将无法正常工作。 该int值不是一个对象。 您必须使用Integer包装类来在HashMap中存储一个int值