-
Conversion d'un tableau en ArrayList .
Pour convertir un tableau en ArrayList , les développeurs utilisent souvent cette méthode :
List<String> list = Arrays.asList(arr);
Arrays.asList()
renverra un objet de classeArrayList
qui est une classe statique privée interne(private static class)
de la classeArrays
, et ce n'est pas une classejava.util.ArrayList.
. La classejava.util.Arrays.ArrayList
contient des méthodesset()
,get()
,contains()
, mais ne contient aucune méthode pour ajouter des éléments, sa taille est fixe . Pour en créer un vraijava.util.ArrayList
, faites ceci :ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
Un constructeur de classe
java.util.ArrayList
peut prendre en paramètre tous les objets qui implémentent une interfaceCollection
dont l'implémentation est héritée par la classe.java.util.Arrays.ArrayList
(la classe statique privée ArrayList<E> étend AbstractList<E> implémente RandomAccess, java.io.Seriallessly).
-
Vérification d'un tableau pour une valeur spécifique.
Les développeurs font souvent ceci :
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);
Le code fonctionne, mais il n'est pas nécessaire de le convertir
List
enSet
. La conversion versSet
prendra plus de temps. En fait, tout est simple :Arrays.asList(arr).contains(targetValue);
ou
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;
La première méthode est beaucoup plus courte.
-
Supprimer un élément d'
List
une boucleConsidérez le code suivant qui supprime des éléments dans une boucle :
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);
Conclusion:
[b, d]
Cela s’avère être une grave erreur. Lorsqu'un élément est supprimé, la taille
List
est réduite et les indices des éléments changent.Évitez donc cette méthode si vous souhaitez supprimer plusieurs éléments dans une boucle à l'aide d'un index.
Vous savez peut-être que l'utilisation d'un itérateur est la bonne solution pour supprimer des éléments dans une boucle, et vous savez qu'une boucle de style
for-each
fonctionne comme un itérateur, mais ce n'est pas le cas.Considérez le code suivant :
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); }
Nous recevrons une ConcurrentModificationException .
La bonne chose à faire est :
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(); } }
La méthode
Dans un style de bouclenext()
doit être appelée avant leremove()
.for-each
, le compilateur appellera la méthoderemove()
, et alors seulementnext()
, ce qui générera une erreurConcurrentModificationException
. Vous pouvez regarder le codeArrayList.iterator()
. -
Hashtable
contreHashMap
.En raison de l'implémentation correspondante, Hashtable est le nom de la structure de données.
Mais en Java , le nom d'une structure de données est
HashMap
. L'une des principales différences entreHashtable
etHashMap
est qu'il estHashtable
synchronisé. Il ne doit donc pas être utiliséHashtable
oùHashMap
.HashMap contre TreeMap contre. Table de hachage vs. LinkedHashMap .
-
Utiliser des collections sans restrictions de contenu
En Java , les collections sans restrictions de contenu sont souvent confondues avec les collections avec un masque de type de contenu. Par exemple, pour les ensembles,
Set
il s'agit d'une collection sans restrictions de contenu, etSet<?>
- d'une collection qui a toujours des restrictions, mais ces restrictions ne limitent en réalité rien. Considérez le code suivant, oùList
il est utilisé sans restrictions comme paramètre de méthode :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); }
Ce code lèvera une exception :
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at …
Utiliser des collections sans restrictions de contenu est très dangereux car vous ne pouvez pas être sûr de ce qu'elles contiennent. Et afin de comprendre toute la profondeur de la différence entre
Set
,Set<?>
etSet<Object>
- lisez ceci et ce lien. -
Niveau d'accès
Très souvent, les développeurs utilisent le modificateur d'accès pour les champs de classe
public
. Cela facilite l’obtention directe de la valeur du champ. Il est plus correct d'utiliser un accès aussi limité que possible aux membres de la classe. ArrayList
contreLinkedList
Lorsque les développeurs ne savent pas en quoi il diffère
ArrayList
deLinkedList
, ils utilisent le premier en raison de sa plus grande popularité. Cependant, il existe une énorme différence de performances entre eux. En fait, le choix entre eux doit être dicté par leurs caractéristiques internes -ArrayList
cela vous permet d'accéder rapidement à un élément arbitraire du tableau, etLinkedList
- d'ajouter/supprimer rapidement des éléments dans le tableau. Lisez l'article sur le lien ArrayList vs. LinkedList pour comprendre les raisons de leurs performances différentes.Mutable
(Modifiable) vsImmutable
(Immuable)Un objet immuable présente de nombreux avantages : simplicité, sécurité, etc. Mais cela nécessite un objet distinct pour chaque nouvelle valeur, et avoir trop d’objets a un coût en termes de performances. Il doit y avoir un équilibre lors du choix entre un objet mutable et un objet immuable.
Fondamentalement, pour éviter de préparer des objets intermédiaires, un objet mutable est utilisé. L’un des exemples classiques est la concaténation d’un grand nombre de chaînes. Si vous utilisez un objet immuable de type
String
, vous créez de nombreux objets qui iront immédiatement au garbage collector. Cela fait perdre du temps et de l'énergie CPU, la bonne solution consiste donc à utiliser des objets mutables (par exempleStringBuilder
).String result=""; for(String s: arr){ result = result + s; }
Un autre exemple d'utilisation d'objets mutables consiste à transmettre un tel objet à une méthode. Cela vous permettra de renvoyer le résultat de la même manière, sans créer d'objets inutiles. Lorsque vous travaillez avec des objets volumineux, tels que des collections, transmettre une collection à une méthode de tri et renvoyer le résultat dans une autre collection est un gaspillage de ressources totalement inutile. ( Réponse de dasblinkenlight sur Stack Overflow ).
-
Constructeurs de classes
Super
etSub
Cette erreur de compilation est due au fait que la classe ancêtre n'a pas de constructeur par défaut défini. En Java , sauf si vous spécifiez vous-même un constructeur de classe, le compilateur créera un constructeur par défaut qui ne nécessite aucun argument. Si le constructeur est décrit dans la classe
Super
commeSuper(String s){}
, le compilateur lui-même n'ajoutera rien. C'est ce que nous voyons dans notre exemple.Le constructeur de la classe
Sub
, quel qu'il soit, appellera le constructeur par défaut de la classeSuper
, puisque rien d'autre n'est spécifié. Puisqu'il n'y a pas de constructeur par défaut dans la classeSuper
, cela entraînera une erreur de compilation.La première solution à ce problème consiste à ajouter un constructeur par défaut à la classe
Super
public Super(){ System.out.println("Super"); }
La deuxième option consiste à supprimer le constructeur que nous avons décrit de la classe
Super
afin que le compilateur crée un constructeur par défaut.Et la dernière option consiste à ajouter un appel
super(value)
aux constructeurs de classeSub
afin que le constructeur de classe existant soit appelé à la place du constructeur par défaut.Super
-
" " ou constructeur ?
Il existe deux manières de créer une chaîne :
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");
Quelle est la différence entre eux?
Vous pouvez le comprendre à partir des exemples suivants :
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
Pour en savoir plus sur la façon dont les chaînes sont stockées en mémoire, lisez Créer une chaîne Java à l'aide de "" ou d'un constructeur ? .
GO TO FULL VERSION