2015-09-06 78 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

只是一個「提示」;我也不爭論。 「技術」廣泛使用(並濫用)......問候! –

相關問題