Quelle est la différence entre ces deux déclarations?
Déclaration 1:
ArrayList<String> arrayList = new ArrayList<String>();
Déclaration 2:
List<String> arrayList = new ArrayList<String>();
List<String> arrayList = new ArrayList<String>();
Est générique lorsque vous souhaitez masquer les détails d'implémentation tout en les renvoyant au client; ultérieurement, vous pouvez modifier l'implémentation de ArrayList
à LinkedList
de manière transparente.
Ce mécanisme est utile dans les cas où vous concevez des bibliothèques, etc., qui peuvent modifier leurs détails d'implémentation à un moment donné avec des modifications minimes du côté client.
ArrayList<String> arrayList = new ArrayList<String>();
Cela vous oblige toujours à retourner ArrayList
. Si, à un moment donné, vous souhaitez modifier les détails d'implémentation en LinkedList
, des modifications doivent également être apportées côté client pour utiliser LinkedList
au lieu de ArrayList
.
List
est une interface et ArrayList
est une implémentation de l'interface List. La classe ArrayList
n'a que quelques méthodes(i.e clone(), trimToSize(), removeRange() and ensureCapacity())
en plus des méthodes disponibles dans l'interface List. Il n'y a pas beaucoup de différence en cela.
1. List<String> l = new ArrayList<>();
2. ArrayList<String> l = new ArrayList<>();
Si vous utilisez la première, vous pourrez appeler les méthodes disponibles dans l'interface List et vous ne pourrez pas appeler les nouvelles méthodes disponibles dans la classe ArrayList
. Où que, vous êtes libre d'utiliser toutes les méthodes disponibles dans la ArrayList
si vous utilisez la seconde.
Je dirais que la première approche est meilleure parce que, lorsque vous développez des applications Java, lorsque vous êtes censé transmettre les objets du cadre de la collection comme arguments aux méthodes, il est préférable d'utiliser la première approche. .
List<String> l = new ArrayList<>();
doSomething(l);
A l'avenir, en raison de contraintes de performances, si vous modifiez l'implémentation pour qu'elle utilise LinkedList
ou d'autres classes implémentant l'interface List
, au lieu de ArrayList
, vous devez changer à un moment donné (le partie instanciation).
List<String> l = new LinkedList<>();
Sinon, vous serez censé changer à tous les endroits, où que vous ayez utilisé l'implémentation de classe spécifique comme arguments de méthode.
La différence est que la variante 1 vous oblige à utiliser un ArrayList
alors que la variante 2 ne vous garantit que tout ce qui implémente List<String>
.
Plus tard, vous pourrez changer cela en List<String> arrayList = new LinkedList<String>();
sans trop de soucis. La variante 1 peut nécessiter que vous changiez non seulement cette ligne, mais également d'autres pièces si elles reposent sur le travail avec un ArrayList<String>
.
J'utiliserais donc List<String>
dans presque tous les cas, sauf lorsque j'aurais besoin d'appeler les méthodes supplémentaires fournies par ArrayList
(ce qui n'a jamais été le cas jusqu'à présent): ensureCapacity(int)
et trimToSize()
.
Fondamentalement, cela permet à Java de stocker plusieurs types d'objets dans une implémentation de structure, par déclaration de type générique (comme class MyStructure<T extends TT>
), qui est l'une des principales caractéristiques de Javas.
Les approches orientées objet sont basées sur la modularité et la réutilisabilité par séparation des préoccupations - la possibilité d'utiliser une structure avec tout type de type d'objet (tant qu'elle obéit à quelques règles).
Vous pouvez simplement instancier les choses comme suit:
ArrayList list = new ArrayList();
au lieu de
ArrayList<String> list = new ArrayList<>();
En déclarant et en utilisant des types génériques, vous indiquez à une structure le type d’objets qu’elle gérera et le compilateur pourra vous informer si vous insérez un type illégal dans cette structure, par exemple. Disons:
// this works
List list1 = new ArrayList();
list1.add(1);
list1.add("one");
// does not work
List<String> list2 = new ArrayList<>();
list2.add(1); // compiler error here
list2.add("one");
Si vous voulez voir quelques exemples, consultez la documentation documentation :
/**
* Generic version of the Box class.
* @param <T> the type of the value being boxed
*/
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
Ensuite, vous pouvez instancier des choses comme:
class Paper { ... }
class Tissue { ... }
// ...
Box<Paper> boxOfPaper = new Box<>();
boxOfPaper.set(new Paper(...));
Box<Tissue> boxOfTissues = new Box<>();
boxOfTissues.set(new Tissue(...));
La principale chose à tirer de cela est que vous spécifiez le type d'objet que vous voulez encadrer.
En ce qui concerne l’utilisation de Object l = new ArrayList<>();
, vous n’avez pas accès à l’implémentation List
ni ArrayList
, vous ne pourrez donc pas faire grand chose avec la collection.
Il est facile de changer l'implémentation en List
en Set
:
Collection<String> stringList = new ArrayList<String>();
//Client side
stringList = new LinkedList<String>();
stringList = new HashSet<String>();
//stringList = new HashSet<>(); Java 1.7 and 1.8
La première déclaration doit être une liste de tableaux, la seconde peut être facilement modifiée en un autre type de liste. En tant que tel, le second est préférable car il indique clairement que vous n'avez pas besoin d'une implémentation spécifique. (Parfois, vous avez vraiment besoin d'une implémentation, mais c'est rare)
Vous pouvez éventuellement vous référer à ce lien http://docs.Oracle.com/javase/6/docs/api/Java/util/List.html
List est une interface.ArrayList, LinkedList, etc. sont des classes qui implémentent list. Lorsque vous utilisez List Interface, vous devez itearte des éléments à l'aide de ListIterator et vous pouvez avancer et revenir en arrière. Dans la liste, comme dans ArrayList, Iterate utilisant Iterator et ses éléments peuvent être accédé de manière unidirectionnelle.
List est interface et ArrayList est une classe concrète implémentée. Il est toujours recommandé d'utiliser.
List<String> arrayList = new ArrayList<String>();
Parce qu'ici la liste de référence est flexible. Il peut également contenir l'objet LinkedList or Vector
.
Il existe quelques cas où vous préférerez peut-être que le premier améliore (légèrement) les performances, par exemple sur certaines machines virtuelles sans compilateur JIT .
Hors de ce genre de contexte très spécifique, vous devriez utiliser le premier.
Chaque fois que vous avez vu le code de la communauté open source comme Guava et de Google Developer (Android Library), ils ont utilisé cette approche.
List<String> strings = new ArrayList<String>();
parce que c'est cacher les détails de mise en œuvre de l'utilisateur. Vous précisément
List<String> strings = new ArrayList<String>();
c'est l'approche générique et cette approche spécialisée
ArrayList<String> strings = new ArrayList<String>();
Pour référence: Effective Java 2nd Edition: Article 52: Faire référence aux objets par leurs interfaces