2015-09-06 54 views
3

比方说,我想为数字创建一个ArrayList。我了解到它的方式是这样的:初始化ArrayList和HashMap的最佳方法是什么?

​​

但IntelliJ IDEA的想要将其修正为

private static List<Integer> numbers = new ArrayList<>(); 

然后,我发现了这个工程,以及:

private static List<Integer> numbers = new ArrayList(); 

现在我困惑,最好的办法是什么?有什么区别。同样的问题适用于HashMap

+4

你的第一个和第二个例子看起来是一样的吗? – snozza

+0

我的不好,纠正了我的问题。 – SJ19

+1

关于第三个选项:请参阅[什么是原始类型,为什么我们不应该使用它?](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-请勿使用-123)请拨打 – Jesper

回答

7

最好的办法是:

private static List<Integer> numbers = new ArrayList<>(); // Java 7 
private static List<Integer> numbers = new ArrayList<Integer>(); // Java 6 

让我们来看看其他的例子:

private static ArrayList<Integer> numbers = new ArrayList<Integer>();使用一个特定的类的类型,除非您需要访问特定的ArrayList的方法不建议使用这种(我不知道)

private static ArrayList<Integer> numbers = new ArrayList();是类型不安全的,并且您的IDE应该在此行上给出警告。

+0

,能否更详细地解释为什么最后一种情况是不安全的?我该怎么做才能得到一个错误? – ka4eli

+0

* private static ArrayList numbers = new ArrayList();是类型不安全的,并且如果你的IDE应该在这一行给你一个警告。*实际上,如果你使用'<>()',android studio会发出警告,建议你只使用'()' –

+1

@ ka4eli,特殊情况下并不重要。但是在其他一些情况下(例如,如果type参数是有界的,或者您使用依赖于类型参数的构造函数参数),它会有所不同。 –

3

您应该使用在左侧的接口:

private static List<Integer> numbers = new ArrayList<>(); 

,除非你真的需要任何的该数据结构的具体方法。

的IntelliJ IDEA是在暗示你,构建因为你使用的是JDK 1.7.x(或上级),也没有必要再次指定,因为编译器infer the type arguments from the context(再次从Java 7和/或更高版本)。

2

所有给出的示例都会编译到相同的字节码不会影响后续的类型检查。使用这个或另一个的原因是避免令人讨厌的警告。

  • new ArrayList();预仿制药方式。编译器会警告你,因为你不关心泛型(并且可能会使用Integer以外的元素分配ArrayList)。
  • new ArrayList<Integer>();是泛型方法,但以前编译器是足够聪明到推断本身的元素类型。因此它会警告你,因为它比必要的更冗长。
  • new ArrayList<>();是目前首选的方式(感谢在Java 7中引入的Type Inferencesee related SO question))。去除它,除非你必须处理较老的编译器。

也许一个有趣的问题是,为什么new ArrayList<>();是最好的(类型推断),但new ArrayList();不是。

1

第一个例子是正确的,你提供所需的一切。但它也意味着您重复参数类型的定义。

然后,在Java 1.7(或者1.8,不太清楚),他们推出的缩短版 - 所以,如果你定义ArrayList<Integer> numbers,没有必要定义再讲ArrayListInteger应创建并只需保持<>那里。这有时称为菱形符号并指示编译器使用与字段定义相同的数据类型。因此,它的行为与第一个例子完全相同,但不需要复制有关数据类型的信息。

您创建的ArrayList没有指定的数据类型,您在那里的最后一种情况有所不同。这可能有点危险,因为它允许你写下面的代码:

List listAnything = new ArrayList(); 
listAnything.add("string"); 
listAnything.add(42); 
listAnything.add(false); 

List<Integer> listInteger = listAnything; 

以上列举的代码编译完全正常,但大约有选中转换和使用原始类型一些警告。您不再保证listInteger仅包含整数。

此外,在这里警告的话 - 你应该尽可能在你的代码中依赖抽象。通过这个我的意思是定义你的领域使用一个接口或抽象类而不是具体的。这样的代码显着更好地阅读和维护:

ArrayList<Integer> list = new ArrayList<>(); // this is not wrong... 
List<Integer> list = new ArrayList<>(); // ...but this is better 
+0

“你应该尽可能在你的代码中尽可能依靠抽象”......对此要小心,90%的时间是不正确的;尽管在真正有用的情况下存在真实的情况(我不是在谈论API开发)。现在,Java正在臃肿,因为...看看许多其他(与Java相类似的)编程语言正在做什么。 –

+0

@ɐuıɥɔɐɯ你为什么这么认为?我的意思是,我不想争辩,只是好奇你的想法。这个“技术”似乎被广泛使用,所以我想知道你在哪里看到问题。另外,我并不是指“随时随地”,而是“尽可能地说”,我假设读者会使用常识:-) –

+0

只是一个“提示”;我也不争论。 “技术”广泛使用(并滥用)......问候! –

相关问题