我所创建的以下地图之间的区别是什么(在另一个问题中,人们似乎可以互换地使用它们,我想知道它们是否/如何不同):

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

当前回答

正如TJ Crowder和Adamski所指出的,一个引用指向一个接口,另一个引用指向接口的特定实现。根据Joshua Block的说法,你应该总是尝试对接口进行编码,以允许你更好地处理底层实现的变化——也就是说,如果HashMap突然不适合你的解决方案,你需要改变映射实现,你仍然可以使用map接口,并改变实例化类型。

其他回答

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

首先,Map是一个接口,它有不同的实现,如HashMap, TreeHashMap, LinkedHashMap等。接口的工作方式类似于实现类的超类。因此,根据面向对象的规则,任何实现Map的具体类也是Map。这意味着我们可以将任何HashMap类型变量赋值/放置到Map类型变量,而不需要任何类型的强制转换。

在这种情况下,我们可以将map1分配给map2,而不需要任何强制转换或丢失数据

map2 = map1

Map是接口,Hashmap是实现接口的类。

在这个实现中,你创建了相同的对象

正如TJ Crowder和Adamski所指出的,一个引用指向一个接口,另一个引用指向接口的特定实现。根据Joshua Block的说法,你应该总是尝试对接口进行编码,以允许你更好地处理底层实现的变化——也就是说,如果HashMap突然不适合你的解决方案,你需要改变映射实现,你仍然可以使用map接口,并改变实例化类型。

你创建了相同的地图。

但是当你使用它的时候,你可以弥补这个差异。对于第一种情况,你将能够使用特殊的HashMap方法(但我不记得有什么真正有用的方法),并且你将能够将它作为HashMap参数传递:

public void foo (HashMap<String, Object) { ... }

...

HashMap<String, Object> m1 = ...;
Map<String, Object> m2 = ...;

foo (m1);
foo ((HashMap<String, Object>)m2); 

Map有以下实现:

HashMap Map m = new HashMap(); LinkedHashMap映射m = new LinkedHashMap(); TreeMap Map m = new TreeMap(); WeakHashMap映射m = new WeakHashMap();

假设您已经创建了一个方法(这只是伪代码)。

public void HashMap getMap(){
   return map;
}

假设你的项目需求改变了:

该方法应该返回映射内容-需要返回HashMap。 该方法应该返回映射键的插入顺序-需要改变返回类型HashMap到LinkedHashMap。 该方法应该按顺序返回映射键-需要将返回类型LinkedHashMap更改为TreeMap。

如果您的方法返回特定的类,而不是实现Map接口的东西,那么您每次都必须更改getMap()方法的返回类型。

但是如果您使用Java的多态性特性,而不是返回特定的类,而是使用接口Map,它将提高代码的可重用性并减少需求更改的影响。