Je voulais créer une liste d'options à des fins de test. Au début, je l'ai fait:
ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");
Ensuite, j'ai refactorisé le code comme suit:
ArrayList<String> places = new ArrayList<String>(
Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
Y a-t-il une meilleure manière de faire cela?
java
collections
arraylist
initialization
Macarse
la source
la source
ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]
Réponses:
En fait, probablement la "meilleure" façon d'initialiser la
ArrayList
est la méthode que vous avez écrite, car elle n'a pas besoin d'en créer une nouvelleList
:Le hic, c'est qu'il y a pas mal de frappe nécessaire pour faire référence à cette
list
instance.Il existe des alternatives, telles que la création d'une classe interne anonyme avec un initialiseur d'instance (également appelée "initialisation à double accolade"):
Cependant, je n'aime pas trop cette méthode parce que vous vous retrouvez avec une sous-classe
ArrayList
qui a un initialiseur d'instance, et cette classe est créée juste pour créer un objet - cela semble juste un peu exagéré pour moi.Ce qui aurait été bien, c'était que la proposition Collection Literals pour Project Coin ait été acceptée (elle devait être introduite dans Java 7, mais elle ne devrait pas non plus faire partie de Java 8):
Malheureusement, cela ne vous aidera pas ici, car il initialisera un immuable
List
plutôt qu'unArrayList
, et en outre, il n'est pas encore disponible, s'il le sera jamais.la source
Ce serait plus simple si vous deviez simplement le déclarer comme
List
- doit-il être un ArrayList?Ou si vous n'avez qu'un seul élément:
Cela signifierait que
places
c'est immuable (essayer de le changer entraînera laUnsupportedOperationException
levée d' une exception).Pour créer une liste mutable concrète,
ArrayList
vous pouvez en créer une àArrayList
partir de la liste immuable:la source
ArrayList
, il serait préférable de modifier la déclaration enList
. Spécifiez les interfaces, pas les implémentations.asList(...)
renvoie une taille fixeList
qui explose lors d'opérations de mutation commeremove
etclear
, ce que leList
contrat prétend prendre en charge. Même si vous avez laissé la déclaration asList
, vous devrez toujours l'utiliserList l = new ArrayList(asList(...))
pour obtenir un objet qui ne lève pas d'exceptions OperationNotSupported. Liskov Principe de substitution quelqu'un?remove
etclear
sont des opérations optionnelles dansList
,asList(...)
suit donc le contrat. Nulle part le PO ne dit qu'il a besoin d'ajouter plus d'éléments plus tard, l'exemple est justeList
celui qui doit être initialisé avec trois éléments.La réponse simple
Dans Java 9 ou version ultérieure, après a
List.of()
été ajouté:Avec Java 10 ou version ultérieure, cela peut être raccourci avec le
var
mot - clé.Cela vous donnera une immuable
List
, donc il ne peut pas être changé.C'est ce que vous voulez dans la plupart des cas où vous le préremplissez.
Java 8 ou version antérieure:
Cela vous donnera un
List
soutenu par un tableau, donc il ne peut pas changer de longueur.Mais vous pouvez appeler
List.set
, donc c'est toujours mutable .Vous pouvez
Arrays.asList
raccourcir encore plus avec une importation statique:L'importation statique:
Ce que n'importe quel IDE moderne suggérera et fera automatiquement pour vous.
Par exemple, dans IntelliJ IDEA, vous appuyez sur
Alt+Enter
et sélectionnezStatic import method...
.Cependant, je ne recommande pas de raccourcir la
List.of
méthodeof
, car cela devient déroutant.List.of
est déjà assez court et se lit bien.En utilisant
Stream
sPourquoi faut-il que ce soit un
List
?Avec Java 8 ou version ultérieure, vous pouvez utiliser un
Stream
qui est plus flexible:Vous pouvez concaténer
Stream
s:Ou vous pouvez passer de a
Stream
à aList
:Mais de préférence, utilisez simplement le
Stream
sans le ramasser à unList
.Si vous avez vraiment besoin d'un
java.util.ArrayList
(Vous ne le faites probablement pas.)
Pour citer JEP 269 (c'est moi qui souligne):
Si vous souhaitez à la fois préremplir un
ArrayList
et y ajouter par la suite (pourquoi?), Utilisezou en Java 8 ou version antérieure:
ou en utilisant
Stream
:Mais encore une fois, il vaut mieux utiliser
Stream
directement le au lieu de le collecter dans unList
.Programme aux interfaces, pas aux implémentations
Vous avez déclaré avoir déclaré la liste en tant que
ArrayList
dans votre code, mais vous ne devriez le faire que si vous utilisez un membre deArrayList
qui n'en fait pas partieList
.Ce que vous ne faites probablement pas.
Habituellement , vous devez simplement déclarer des variables par la plus interface générale que vous allez utiliser (par exemple
Iterable
,Collection
ouList
), et les initialiser avec la mise en œuvre spécifique (par exempleArrayList
,LinkedList
ouArrays.asList()
).Sinon, vous limitez votre code à ce type spécifique, et il sera plus difficile de changer quand vous le souhaitez.
Par exemple, si vous passez d'un
ArrayList
à unvoid method(...)
:Un autre exemple serait de toujours déclarer une variable an
InputStream
même s'il s'agit généralement d'unFileInputStream
ou d'unBufferedInputStream
, car un jour prochain, vous ou quelqu'un d'autre voudrez utiliser un autre type deInputStream
.la source
Arrays.asList
est une méthode statique. Voir docs.oracle.com/javase/1.5.0/docs/guide/language/…Si vous avez besoin d'une simple liste de taille 1:
Si vous avez besoin d'une liste de plusieurs objets:
la source
Avec la goyave, vous pouvez écrire:
À Guava, il existe également d'autres constructeurs statiques utiles. Vous pouvez en lire plus ici .
la source
java.util.Arrays
par exemple,List<String> names = Arrays.asList("Beckah", "Sam", "Michael");
Les littéraux de collection ne sont pas entrés dans Java 8, mais il est possible d'utiliser l'API Stream pour initialiser une liste sur une assez longue ligne:
Si vous devez vous assurer que vous êtes
List
unArrayList
:la source
Avec java-9et au-dessus, comme suggéré dans JEP 269: Convenience Factory Methods for Collections , ceci pourrait être réalisé en utilisant les littéraux de collection maintenant avec -
Une approche similaire s'appliquerait
Map
également -qui est similaire à la proposition Collection Literals comme indiqué par @coobird. Également clarifié dans le JEP -
Alternatives
En relation: Quel est l'intérêt des méthodes surchargées de Convenience Factory pour les collections dans Java 9
la source
la source
Collections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"))
, ce qui devientunmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata"))
avec les importations statiques. Vous n'avez pas besoin de Google Collections pour cela.ImmutableList
à d'autres méthodes qui prennent unList
, puis vous avez de toute façon perdu cette documentation.Vous pouvez créer une méthode d'usine:
Mais ce n'est pas beaucoup mieux que votre premier refactoring.
Pour plus de flexibilité, il peut être générique:
la source
Dans Java 9, nous pouvons facilement initialiser un
ArrayList
sur une seule ligne:ou
Cette nouvelle approche de Java 9 présente de nombreux avantages par rapport aux précédentes:
Voir cet article pour plus de détails -> Quelle est la différence entre List.of et Arrays.asList?
la source
À propos de la façon la plus compacte de procéder:
la source
Utilisez simplement le code ci-dessous comme suit.
la source
Avec Eclipse Collections, vous pouvez écrire ce qui suit:
Vous pouvez également être plus précis sur les types et s'ils sont mutables ou immuables.
Vous pouvez également faire de même avec les ensembles et les sacs:
Remarque: je suis un committer pour les collections Eclipse.
la source
Voici une autre façon:
la source
(Doit être un commentaire, mais trop long, donc nouvelle réponse). Comme d'autres l'ont mentionné, la
Arrays.asList
méthode est de taille fixe, mais ce n'est pas le seul problème. Il ne gère pas non plus très bien l'héritage. Par exemple, supposons que vous ayez les éléments suivants:Ce qui précède entraîne une erreur de compilation, car
List<B>
(ce qui est renvoyé par Arrays.asList) n'est pas une sous-classe deList<A>
, même si vous pouvez ajouter des objets de type B à unList<A>
objet. Pour contourner cela, vous devez faire quelque chose comme:C'est probablement la meilleure façon de procéder, en particulier. si vous avez besoin d'une liste illimitée ou devez utiliser l'héritage.
la source
Vous pouvez utiliser les déclarations ci-dessous:
Extrait de code:
la source
letters = Arrays.asList(new String[]{"A", "B", "C"});
Comme l'a dit Tom :
Mais puisque vous vous êtes plaint de vouloir une ArrayList, vous devez d'abord savoir que ArrayList est une sous-classe de List et vous pouvez simplement ajouter cette ligne:
Cependant, cela pourrait vous faire vous plaindre de «performances».
Dans ce cas, cela n'a pas de sens pour moi, pourquoi, puisque votre liste est prédéfinie, elle n'a pas été définie comme un tableau (car la taille est connue au moment de l'initialisation). Et si c'est une option pour vous:
Si vous ne vous souciez pas des différences de performances mineures, vous pouvez également copier un tableau dans une liste de tableaux très simplement:
D'accord, mais à l'avenir, vous aurez besoin d'un peu plus que le nom du lieu, vous avez également besoin d'un code de pays. En supposant qu'il s'agit toujours d'une liste prédéfinie qui ne changera jamais pendant l'exécution, il convient d'utiliser un
enum
ensemble, qui nécessiterait une recompilation si la liste devait être modifiée à l'avenir.deviendrait:
Les
values
énumérations ont une méthode statique qui renvoie un tableau contenant toutes les valeurs de l'énumération dans l'ordre où elles sont déclarées, par exemple:Dans ce cas, je suppose que vous n'auriez pas besoin de votre ArrayList.
PS Randyaa a démontré une autre belle façon d'utiliser la méthode utilitaire statique Collections.addAll .
la source
Java 9 a la méthode suivante pour créer une liste immuable :
qui est facilement adapté pour créer une liste mutable, si nécessaire:
Des méthodes similaires sont disponibles pour
Set
etMap
.la source
la source
Oui, à l'aide des tableaux, vous pouvez initialiser la liste des tableaux sur une seule ligne,
la source
Vous pouvez utiliser
StickyList
de Cactoos :la source
Essayez avec cette ligne de code:
la source
En Java, vous ne pouvez pas faire
Comme cela a été souligné, vous devez effectuer une initialisation à double accolade:
Mais cela peut vous forcer à ajouter une annotation
@SuppressWarnings("serial")
ou générer un UUID série qui est ennuyeux. De plus, la plupart des formateurs de code déplieront cela en plusieurs instructions / lignes.Vous pouvez également faire
mais alors vous voudrez peut-être faire un
@SuppressWarnings("unchecked")
.Toujours selon javadoc, vous devriez pouvoir faire ceci:
Mais je ne parviens pas à le compiler avec JDK 1.6.
la source
Si vous aviez besoin d'avoir une liste d' un article !
Les collections proviennent du package java.util .
la source
La meilleure façon de le faire:
Créez simplement une fonction qui peut avoir autant d'éléments que vous le souhaitez et appelez-la pour les ajouter sur une seule ligne.
la source
Object
.Voici le code d' AbacusUtil
Déclaration: je suis le développeur d'AbacusUtil.
la source
Pour moi, Arrays.asList () est le meilleur et le plus pratique. J'aime toujours initialiser de cette façon. Si vous êtes un débutant dans les collections Java, je voudrais que vous fassiez référence à l' initialisation de ArrayList
la source
add()
méthodes?Pourquoi ne pas faire une fonction utilitaire simple qui fait cela?
"
ll
" signifie "liste littérale".la source
fait intéressant, aucun one-liner avec l'autre méthode surchargée
Stream::collect
n'est répertoriéla source
En fait, il est possible de le faire en une seule ligne:
la source