-
Conversione di un array in un ArrayList .
Per convertire un array in un ArrayList , gli sviluppatori utilizzano spesso questo metodo:
List<String> list = Arrays.asList(arr);
Arrays.asList()
restituirà un oggetto di classeArrayList
che è una classe statica privata interna(private static class)
della classeArrays
e questa non è una classe.java.util.ArrayList.
La classejava.util.Arrays.ArrayList
contiene metodiset()
,get()
,contains()
, ma non contiene alcun metodo per aggiungere elementi, la sua dimensione è fissa . Per crearne uno verojava.util.ArrayList
, fai questo:ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
Un costruttore di classe
java.util.ArrayList
può prendere come parametro tutti gli oggetti che implementano un'interfacciaCollection
, la cui implementazione è ereditata dalla classejava.util.Arrays.ArrayList
(la classe statica privata ArrayList<E> estende AbstractList<E> implementa RandomAccess, java.io.Serializable).
-
Controllo di un array per un valore specifico.
Gli sviluppatori spesso fanno così:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);
Il codice funziona, ma non è necessario convertirlo
List
inSet
. La conversione inSet
richiederà più tempo. In effetti, tutto è semplice:Arrays.asList(arr).contains(targetValue);
O
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;
Il primo metodo è molto più breve.
-
Rimozione di un elemento da
List
un cicloConsidera il seguente codice che rimuove gli elementi in un ciclo:
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);
Conclusione:
[b, d]
Questo si rivela un grave errore. Quando un elemento viene rimosso, la dimensione
List
viene ridotta e gli indici dell'elemento cambiano.Quindi evita questo metodo se desideri rimuovere più elementi in un ciclo utilizzando un indice.
Potresti sapere che l'utilizzo di un iteratore è la soluzione corretta per rimuovere elementi in un ciclo e sai che un ciclo di stile
for-each
funziona come un iteratore, ma non è così.Considera il seguente codice:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); }
Riceveremo una ConcurrentModificationException .
La cosa corretta da fare è:
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(); } }
Il metodo
In uno stile loopnext()
deve essere chiamato prima delremove()
.for-each
, il compilatore chiamerà il metodoremove()
e, solo alloranext()
, genererà un erroreConcurrentModificationException
. Puoi guardare il codiceArrayList.iterator()
. -
Hashtable
controHashMap
.A causa della corrispondente implementazione, Hashtable è il nome della struttura dati.
Ma in Java il nome di una struttura dati è
HashMap
. Una delle differenze principali traHashtable
eHashMap
è che èHashtable
sincronizzato, quindi non dovrebbe essere utilizzatoHashtable
doveHashMap
.HashMap vs. Mappa ad albero vs. Tabella hash vs. LinkedHashMap .
-
Utilizza le raccolte senza restrizioni sui contenuti
В 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
Questo errore di compilazione è causato dal fatto che la classe antenata non ha un costruttore predefinito definito. In Java , a meno che tu non specifichi tu stesso un costruttore di classe, il compilatore creerà un costruttore predefinito che non richiede argomenti. Se il costruttore è descritto nella classe
Super
comeSuper(String s){}
, il compilatore stesso non aggiungerà nulla. Questo è ciò che vediamo nel nostro esempio.Il costruttore della classe
Sub
, non importa quale, chiamerà il costruttore predefinito della classeSuper
, poiché non è specificato nient'altro. Poiché non esiste un costruttore predefinito nella classeSuper
, ciò porterà a un errore di compilazione.La prima soluzione a questo problema è aggiungere un costruttore predefinito alla classe
Super
public Super(){ System.out.println("Super"); }
La seconda opzione è rimuovere il costruttore descritto dalla classe
Super
in modo che il compilatore crei un costruttore predefinito.E l'ultima opzione è aggiungere una chiamata
super(value)
ai costruttori di classeSub
in modo che venga chiamato il costruttore di classe esistente invece del costruttore predefinitoSuper
-
" " o costruttore?
Esistono due modi per creare una stringa:
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");
Qual'è la differenza tra loro?
Puoi capirlo dai seguenti esempi:
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
Per ulteriori informazioni su come le stringhe vengono archiviate in memoria, leggi Creare una stringa Java utilizzando "" o Costruttore? .
GO TO FULL VERSION