我所创建的以下地图之间的区别是什么(在另一个问题中,人们似乎可以互换地使用它们,我想知道它们是否/如何不同):
HashMap<String, Object> map = new HashMap<String, Object>();
Map<String, Object> map = new HashMap<String, Object>();
我所创建的以下地图之间的区别是什么(在另一个问题中,人们似乎可以互换地使用它们,我想知道它们是否/如何不同):
HashMap<String, Object> map = new HashMap<String, Object>();
Map<String, Object> map = new HashMap<String, Object>();
当前回答
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
其他回答
正如TJ Crowder和Adamski所指出的,一个引用指向一个接口,另一个引用指向接口的特定实现。根据Joshua Block的说法,你应该总是尝试对接口进行编码,以允许你更好地处理底层实现的变化——也就是说,如果HashMap突然不适合你的解决方案,你需要改变映射实现,你仍然可以使用map接口,并改变实例化类型。
Map是接口,Hashmap是实现接口的类。
在这个实现中,你创建了相同的对象
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是动态类型的映射。这意味着编译器将把您的map对象视为map类型之一,即使在运行时,它可能指向它的任何子类型。
这种针对接口而不是实现进行编程的实践具有保持灵活性的额外好处:例如,您可以在运行时替换映射的动态类型,只要它是map的子类型(例如LinkedHashMap),并动态地更改映射的行为。
一个好的经验法则是在API级别上尽可能保持抽象:例如,如果您正在编程的方法必须在Map上工作,那么将参数声明为Map而不是更严格的(因为不太抽象)HashMap类型就足够了。这样,API的使用者就可以灵活地决定他们想要传递给方法的Map实现的类型。
在第二个示例中,“map”引用的类型是map,它是由HashMap(和其他类型的map)实现的接口。这个接口是一个契约,表示对象将键映射到值,并支持各种操作(例如put, get)。它没有提到Map(在本例中是HashMap)的实现。
第二种方法通常是首选的,因为您通常不希望将特定的映射实现公开给使用map或通过API定义的方法。