这些初始化HashMap的方法有什么区别?
我为我的程序使用了HashMap,它工作正常,但我不明白这些HashMap初始化之间的区别。
假设我正在实现一个HashMap,其中一个字符作为键,一个整数作为值。 这些有什么区别?
HashMap alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); Map alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap(); Map alphabet1 = new HashMap();
任何涉及没有类型参数的HashMap
或Map
(尖括号<和>以及它们之间的部分)都是原始类型,不应使用 。 原始类型不是通用的,可以让您做出不安全的事情。
“正确”的方式是
Map alphabet1 = new HashMap(); HashMap alphabet1 = new HashMap();
第一个使用接口Map作为引用类型。 它通常更具惯用性和良好的风格 。
另一种方法是你没有提到, 使用Java 7钻石操作符
Map alphabet1 = new HashMap<>(); HashMap alphabet1 = new HashMap<>();
这或多或少等同于前两种正确的方法。 左侧的引用类型的参数隐式提供给右侧的构造函数。
你错过了正确的选择:
Map alphabet1 = new HashMap();
- generics声明允许编译器在编译期间检查“alphabet1”用法。
- 左侧的Map / HashMap声明了如何考虑’alphabet1’变量:作为Map(接口)或HashMap(具体类的实例)。 当然首选接口 – 它使您的代码对进一步更改更加健壮。
HashMap alphabet1 = new HashMap(); // (1)
(1)在不使用generics的情况下初始化HashMap
,但之后使用带有generics的HashMap
进行不安全的HashMap
。 这应该引发编译器警告。
HashMap alphabet1 = new HashMap(); // (2)
(2)用generics初始化HashMap
,并用generics声明HashMap
类型的变量。 它可以简称为
HashMap alphabet1 = new HashMap<>(); // (2b)
这里,编译器使用类型推断从左侧的声明推断HashMap
的genrics。
HashMap alphabet1 = new HashMap(); // (3)
(3)用generics初始化HashMap,但变量alphabet1
不重用generics信息。 因此,您无法以通用方式访问此HashMap
值的方法(例如,在调用alphabet1.get('a')
而不是强制转换为Integer
时,您将获得一个转换为java.lang.Object
的值)。
Map alphabet1 = new HashMap(); // (4)
(4)类似于(3)但是在这里, alphabet1
是用Map
而不是HashMap
键入的。 因此,您无法访问在HashMap
中定义的方法,也无法访问其超级接口Map
定义的方法。
HashMap alphabet1 = new HashMap(); // (5)
(5)类似于(3),它不使用generics来初始化HashMap
。
Map alphabet1 = new HashMap(); // (6)
(6)类似于(4)并且不使用generics来初始化HashMap
。