-
將數組轉換為ArrayList。
要將陣列轉換為ArrayList,開發人員經常使用以下方法:
List<String> list = Arrays.asList(arr);
Arrays.asList()
會傳回一個類對象,它是該類的ArrayList
內部私有靜態類,並且這不是一個類,該類包含方法,,,但不包含任何添加元素的方法,其大小是固定的。要創建一個真正的,請執行以下操作:(private static class)
Arrays
java.util.ArrayList.
java.util.Arrays.ArrayList
set()
get()
contains()
java.util.ArrayList
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
類別建構子
java.util.ArrayList
可以將所有實作介面的物件作為參數Collection
,該介面的實作由類別繼承。java.util.Arrays.ArrayList
(私有靜態類別 ArrayList<E> 擴充 AbstractList<E> 實作 RandomAccess、java.io.Serializable)。
-
檢查數組中的特定值。
開發人員經常這樣做:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);
該代碼可以工作,但無需將其轉換
List
為Set
. 轉換為Set
將需要額外的時間。其實一切都很簡單:Arrays.asList(arr).contains(targetValue);
或者
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;
第一種方法要短得多。
-
List
從循環中刪除元素考慮以下在循環中刪除元素的程式碼:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (int i = 0; i < list.size(); i++) { list.remove(i); } System.out.println(list);
結論:
[b, d]
事實證明這是一個嚴重的錯誤。當刪除元素時,大小
List
會減少並且元素索引會發生變化。因此,如果您想使用索引刪除循環中的多個元素,請避免使用此方法。
您可能知道使用迭代器是刪除循環中元素的正確解決方案,並且您知道樣式循環的
for-each
工作方式類似於迭代器,但事實並非如此。考慮以下程式碼:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); }
我們將收到一個ConcurrentModificationException。
正確的做法是:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); Iterator<String> iter = list.iterator(); while (iter.hasNext()) { String s = iter.next(); if (s.equals("a")) { iter.remove(); } }
該方法
在循環風格中next()
必須在 之前調用remove()
。for-each
,編譯器將呼叫該方法remove()
,只有在那時next()
,才會引發錯誤ConcurrentModificationException
。你可以看一下程式碼ArrayList.iterator()
。 -
Hashtable
反對HashMap
。由於對應的實現,Hashtable是資料結構的名稱。
但在Java中,資料結構的名稱是
HashMap
。Hashtable
和之間的主要區別之一HashMap
是它是Hashtable
同步的,因此不應該Hashtable
在 where 中使用HashMap
。 -
使用沒有內容限制的集合
В Java часто путают коллекции без ограничений по содержимому, и коллекции с маской по типу содержимого. К примеру, для множеств -
Set
это коллекция без ограничений по содержимому, аSet<?>
— коллекция у которой все-таки есть ограничения, но эти ограничения ничего на самом деле не ограничивают. Рассмотрим следующий code, гдеList
без ограничений используется в качестве параметра метода:public static void add(List list, Object o){ list.add(o); } public static void main(String[] args){ List<String> list = new ArrayList<String>(); add(list, 10); String s = list.get(0); }
Данный code выбросит исключение:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at …
Использование коллекций без ограничений по содержимому очень опасно, потому что вы не можете быть уверенными в том что там лежит внутри. А для того чтобы понять всю глубину разницы между
Set
,Set<?>
иSet<Object>
— почитайте вот эту и эту ссылки. -
Уровень доступа
Очень часто для полей класса разработчики используют модификатор доступа
public
. Так проще получить meaning поля напрямую. Правильнее использовать How можно более ограниченный доступ к членам класса. ArrayList
противLinkedList
Когда разработчики не знают чем отличается
ArrayList
отLinkedList
, они используют первый в силу его большей известности. Однако, есть огромная разница в производительности между ними. На самом деле, выбор между ними должен быть продиктован их внутренними особенностями —ArrayList
позволяет быстро производить доступ к произвольному элементу массива, аLinkedList
— быстро добавлять/удалять элементы в массиве. Почитайте статью по ссылке ArrayList vs. LinkedList чтобы понять причины их разной производительности.Mutable
(Изменяемый) противImmutable
(Неизменяемый)Неизменяемый an object имеет много преимуществ: простота, безопасность и т.д. Но он требует отдельного an object для каждого нового значения, и за слишком большое количество an objectов придется заплатить понижением производительности. Должен быть баланс при выборе между изменяемым и неизменяемым обьектом.
В основном чтобы избежать подготовки промежуточных an objectов используется изменяемый an object. Один из классических примеров это конкатенация большого количества строк. Если вы используете неизменяемый an object типа
String
, то вы создаете много an objectов, которые сразу попадут в сборщик мусора. Это тратит время и энергию процессора, поэтому правильное решение это использование изменяемых обьектов (напримерStringBuilder
).String result=""; for(String s: arr){ result = result + s; }
Еще один пример использования изменяемых an objectов — передача такого an object в метод. Это позволит вернуть результат в нем же, без создания лишних an objectов. При работе с an objectми большого размера, к примеру коллекциями, передача коллекции в метод для сортировки и возвращение результата в другой коллекции приводит к совершенно излишнему расходу ресурсов. (Ответ пользователя dasblinkenlight на Stack Overflow).
-
Конструкторы классов
Super
иSub
這個編譯錯誤是由於祖先類別沒有定義預設的構造函數所導致。在Java中,除非您自己指定類別建構函數,否則編譯器將建立一個不需要參數的預設建構函數。如果建構函式在類別中描述
Super
為Super(String s){}
,則編譯器本身不會添加任何內容。這就是我們在範例中看到的。類別的建構函數
Sub
,無論是哪一個,都會呼叫該類別的預設建構函數Super
,因為沒有指定其他內容。由於類別中沒有預設建構函數Super
,這將導致編譯錯誤。解決這個問題的第一個方法是給類別添加一個預設建構函數
Super
public Super(){ System.out.println("Super"); }
第二個選項是從類別中刪除我們描述的建構函數
Super
,以便編譯器建立預設建構函數。最後一個選項是添加
super(value)
對類別建構函數的調用Sub
,以便調用現有的類別建構函數而不是預設建構函數Super
-
「」還是構造函數?
建立字串有兩種方法:
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");
它們之間有什麼區別?
您可以透過以下範例來理解這一點:
String a = "abcd"; String b = "abcd"; System.out.println(a == b); // True System.out.println(a.equals(b)); // True String c = new String("abcd"); String d = new String("abcd"); System.out.println(c == d); // False System.out.println(c.equals(d)); // True
要了解有關字串如何儲存在記憶體中的更多信息,請閱讀使用“”或構造函數創建 Java 字串?。
GO TO FULL VERSION