Initialisation d’une ArrayList sur une ligne

Je veux créer une liste d’options à des fins de test. Au début, j’ai fait ceci:

ArrayList places = new ArrayList(); places.add("Buenos Aires"); places.add("Córdoba"); places.add("La Plata"); 

Puis j’ai refait le code comme suit:

 ArrayList places = new ArrayList( Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 

Y a-t-il une meilleure manière de faire cela?

En fait, la méthode la plus ArrayList pour initialiser ArrayList est probablement la méthode que vous avez écrite, car elle n’a pas besoin de créer une nouvelle List :

 ArrayList list = new ArrayList(); list.add("A"); list.add("B"); list.add("C"); 

Le problème est qu’il faut un peu de typage pour faire référence à cette instance de list .

Il existe des alternatives, telles que la création d’une classe interne anonyme avec un initialiseur d’instance (également appelé “initialisation par double accolade”):

 ArrayList list = new ArrayList() {{ add("A"); add("B"); add("C"); }}; 

Cependant, je n’aime pas trop cette méthode parce que vous vous retrouvez avec une sous-classe de ArrayList qui a un initialiseur d’instance, et cette classe est créée juste pour créer un object – cela me semble un peu exagéré .

Ce qui aurait été bien, c’était que la proposition de Collection Literals pour Project Coin soit acceptée (elle devait être introduite dans Java 7, mais elle ne devrait pas non plus faire partie de Java 8):

 List list = ["A", "B", "C"]; 

Malheureusement, cela ne vous aidera pas ici, car cela initialisera une List immuable plutôt qu’une List ArrayList , et de plus, elle n’est pas encore disponible, si jamais elle le sera.

Il serait plus simple de simplement le déclarer comme une List – doit-il être une liste de tableaux?

 List places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata"); 

Ou si vous n’avez qu’un seul élément:

 List places = Collections.singletonList("Buenos Aires"); 

Cela voudrait dire que les places sont immuables (essayer de les changer entraînera la levée d’une exception UnsupportedOperationException ).

Pour créer une liste modifiable qui est une ArrayList concrète, vous pouvez créer une ArrayList partir de la liste immuable:

 ArrayList places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 

La réponse simple

En Java 8 ou antérieur:

 List ssortingngs = Arrays.asList("foo", "bar", "baz"); 

Cela vous donnera une List sauvegardée par le tableau, elle ne peut donc pas changer de longueur.
Mais vous pouvez appeler List.set , il est donc encore mutable.


En Java 9:

 List ssortingngs = List.of("foo", "bar", "baz"); 

Cela vous donnera une List immuable, elle ne peut donc pas être modifiée.
C’est ce que vous voulez dans la plupart des cas où vous le pré-remplissez.


La réponse la plus courte

Vous pouvez rendre Arrays.asList encore plus court avec une importation statique:

 List ssortingngs = asList("foo", "bar", "baz"); 

L’importation statique:

 import static java.util.Arrays.asList; 

Ce que tout IDE moderne suggérera et fera automatiquement pour vous.
Par exemple, dans IntelliJ IDEA, appuyez sur Alt+Enter et sélectionnez Static import method...


Cependant, je ne recommande pas de raccourcir la méthode Java 9 List.of , car le fait d’en avoir devient confus.
List.of est déjà assez court et se lit bien.


Utiliser les Stream s

Pourquoi doit-il être une List ?
Avec Java 8 ou version ultérieure, vous pouvez utiliser un Stream plus flexible:

 Stream ssortingngs = Stream.of("foo", "bar", "baz"); 

Vous pouvez concaténer Stream s:

 Stream ssortingngs = Stream.concat(Stream.of("foo", "bar"), Stream.of("baz", "qux")); 

Ou vous pouvez passer d’un Stream à une List :

 List ssortingngs = Stream.of("foo", "bar", "baz").collect(toList()); 

Mais de préférence, utilisez simplement le Stream sans le collecter dans une List .


Si vous avez vraiment besoin de java.util.ArrayList

(Vous ne le faites probablement pas.)
Pour citer JEP 269 (c’est moi qui souligne):

Il existe un petit ensemble de cas d’utilisation pour initialiser une instance de collection mutable avec un ensemble de valeurs prédéfini. Il est généralement préférable d’avoir ces valeurs prédéfinies dans une collection immuable, puis d’initialiser la collection mutable via un constructeur de copie.


Si vous voulez à la fois préremplir une ArrayList et y append ultérieurement (pourquoi?), Utilisez

 List ssortingngs = new ArrayList<>(asList("foo", "bar", "baz")); 

ou en Java 9:

 List ssortingngs = new ArrayList<>(List.of("foo", "bar", "baz")); 

ou en utilisant Stream :

 List ssortingngs = Stream.of("foo", "bar", "baz") .collect(toCollection(ArrayList::new)); 

Mais encore une fois, il est préférable d’utiliser le Stream directement au lieu de le collecter dans une List .


Programme d’interfaces, pas d’implémentations

Vous avez dit que vous avez déclaré la liste comme ArrayList dans votre code, mais vous ne devriez le faire que si vous utilisez un membre de ArrayList qui ne ArrayList pas dans List .

Ce que vous ne faites probablement pas.

Habituellement, vous devez simplement déclarer les variables par l’interface la plus générale que vous allez utiliser (par exemple, Iterable , Collection ou List ) et les initialiser avec l’implémentation spécifique (par exemple ArrayList , LinkedList ou Arrays.asList() ).

Sinon, vous limitez votre code à ce type spécifique et il sera plus difficile de le modifier lorsque vous le souhaitez.

Par exemple:

 // Iterable if you just need iteration, for (Ssortingng s : ssortingngs): Iterable ssortingngs = new ArrayList<>(); // Collection if you also need .size() or .stream(): Collection ssortingngs = new ArrayList<>(); // List if you also need .get(index): List ssortingngs = new ArrayList<>(); // Don't declare a specific list implementation // unless you're sure you need it: ArrayList ssortingngs = new ArrayList<>(); // You don't need ArrayList 

Un autre exemple serait de toujours déclarer variable un InputStream même s’il s’agit généralement d’un FileInputStream ou d’un BufferedInputStream , car bientôt vous ou quelqu’un d’autre voudrez utiliser un autre type de InputStream .

Si vous avez besoin d’une liste simple de taille 1:

 List ssortingngs = new ArrayList(Collections.singletonList("A")); 

Si vous avez besoin d’une liste de plusieurs objects:

 List ssortingngs = new ArrayList(); Collections.addAll(ssortingngs,"A","B","C","D"); 

Avec Guava, vous pouvez écrire:

 ArrayList places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata"); 

Dans Guava, il existe également d’autres constructeurs statiques utiles. Vous pouvez lire à leur sujet ici .

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 dans une ligne plutôt longue:

 List places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toList()); 

Si vous devez vous assurer que votre List est une liste de ArrayList :

 ArrayList places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new)); 
 import com.google.common.collect.ImmutableList; .... List places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata"); 

Vous pouvez créer une méthode d’usine:

 public static ArrayList createArrayList(Ssortingng ... elements) { ArrayList list = new ArrayList(); for (Ssortingng element : elements) { list.add(element); } return list; } .... ArrayList places = createArrayList( "São Paulo", "Rio de Janeiro", "Brasília"); 

Mais ce n’est pas beaucoup mieux que votre premier refactoring.

Pour plus de flexibilité, il peut être générique:

 public static  ArrayList createArrayList(T ... elements) { ArrayList list = new ArrayList(); for (T element : elements) { list.add(element); } return list; } 

Avec Java 9 , comme suggéré dans JDK Enhancement Proposal – 269 , ceci pourrait être réalisé en utilisant les littéraux de collection maintenant –

 List list = List.of("A", "B", "C"); Set set = Set.of("A", "B", "C"); 

Une approche similaire s’appliquerait également à Map

 Map map = Map.of("k1", "v1", "k2", "v2", "k3", "v3") 

ce qui est similaire à la proposition Collection Literals comme indiqué par @coobird également. Précisé dans le document du JEP également –


Des alternatives

Les changements de langue ont été envisagés plusieurs fois et rejetés:

Proposition de pièce de projet, 29 mars 2009

Proposition de pièce de projet, 30 mars 2009

Discussion JEP 186 sur Lambda-Dev, janvier-mars 2014

Les propositions linguistiques ont été mises de côté de préférence à une proposition basée sur la bibliothèque, comme résumé dans ce message.

Enchaîné lu à propos de la même ~> Quel est le sharepoint surchargé Convenience Factory Methods

En Java 9, nous pouvons facilement initialiser une ArrayList sur une seule ligne:

 List places = List.of("Buenos Aires", "Córdoba", "La Plata"); 

ou

 List places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata")); 

Cette nouvelle approche de Java 9 présente de nombreux avantages par rapport aux précédents:

  1. Efficacité spatiale
  2. Immutabilité
  3. Thread Safe

Voir ce post pour plus de détails -> Quelle est la différence entre List.of et Arrays.asList?

A propos de la manière la plus compacte de procéder, voici:

 Double array[] = { 1.0, 2.0, 3.0}; List list = Arrays.asList(array); 

Avec Eclipse Collections (anciennement GS Collections ), vous pouvez écrire ce qui suit:

 List list = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata"); 

Vous pouvez également être plus précis sur les types et savoir s’ils sont modifiables ou immuables.

 MutableList mList = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata"); ImmutableList iList = Lists.immutable.with("Buenos Aires", "Córdoba", "La Plata"); 

Vous pouvez également faire la même chose avec Sets et Bags:

 Set set = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata"); MutableSet mSet = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata"); ImmutableSet iSet = Sets.immutable.with("Buenos Aires", "Córdoba", "La Plata"); Bag bag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata"); MutableBag mBag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata"); ImmutableBag iBag = Bags.immutable.with("Buenos Aires", "Córdoba", "La Plata"); 

Note: Je suis un committer pour les collections Eclipse.

Utilisez simplement le code ci-dessous comme suit.

 List list = new ArrayList() {{ add("A"); add("B"); add("C"); }}; 

Voici une autre façon:

 List values = Stream.of("One", "Two").collect(Collectors.toList()); 

Vous pouvez utiliser les déclarations ci-dessous:

Extrait de code:

 Ssortingng [] arr = {"Sharlock", "Homes", "Watson"}; List names = Arrays.asList(arr); 

(Devrait être un commentaire, mais trop long, donc nouvelle réponse). Comme d’autres l’ont mentionné, la méthode Arrays.asList une taille fixe, mais ce n’est pas le seul problème. Il ne gère pas très bien l’inheritance. Par exemple, supposons que vous ayez les éléments suivants:

 class A{} class B extends A{} public List getAList(){ return Arrays.asList(new B()); } 

Le résultat ci-dessus entraîne une erreur de compilation, car List (qui est renvoyé par Arrays.asList) n’est pas une sous-classe de List , même si vous pouvez append des objects de type B à un object List . Pour contourner ce problème, vous devez faire quelque chose comme:

 new ArrayList(Arrays.asList(b1, b2, b3)) 

C’est probablement la meilleure façon de procéder, surtout si vous avez besoin d’une liste illimitée ou avez besoin d’utiliser l’inheritance.

Comme Tom a dit :

 List places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata"); 

Mais puisque vous vous êtes plaint de vouloir une ArrayList, vous devez d’abord savoir que ArrayList est une sous-classe de List et que vous pouvez simplement append cette ligne:

 ArrayList myPlaces = new ArrayList(places); 

Cependant, cela pourrait vous amener à vous plaindre de «performance».

Dans ce cas, cela n’a pas de sens pour moi, puisque votre liste étant prédéfinie, elle n’a pas été définie comme un tableau (puisque la taille est connue au moment de l’initialisation). Et si c’est une option pour vous:

 Ssortingng[] places = {"Buenos Aires", "Córdoba", "La Plata"}; 

Si vous ne tenez pas compte des différences de performances mineures, vous pouvez également copier un tableau dans une ArrayList très simplement:

 ArrayList myPlaces = new ArrayList(Arrays.asList(places)); 

Ok, mais dans le futur, vous avez besoin d’un peu plus que le nom du lieu, vous avez également besoin d’un code de pays. En supposant qu’il s’agisse toujours d’une liste prédéfinie qui ne changera jamais au cours de l’exécution, il convient d’utiliser un ensemble d’ enum , qui nécessiterait une enum si la liste devait être modifiée ultérieurement.

 enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA} 

deviendrait:

 enum Places { BUENOS_AIRES("Buenos Aires",123), CORDOBA("Córdoba",456), LA_PLATA("La Plata",789); Ssortingng name; int code; Places(Ssortingng name, int code) { this.name=name; this.code=code; } } 

Enum dispose d’une méthode de values statiques qui retourne un tableau contenant toutes les valeurs de l’énum dans l’ordre où elles sont déclarées, par exemple:

 for (Places p:Places.values()) { System.out.printf("The place %s has code %d%n", p.name, p.code); } 

Dans ce cas, je suppose que vous n’auriez pas besoin de votre ArrayList.

PS Randyaa a démontré une autre manière d’utiliser la méthode utilitaire statique Collections.addAll .

Java 9 a la méthode suivante pour créer une liste immuable :

 List places = List.of("Buenos Aires", "Córdoba", "La Plata"); 

qui est facilement adapté pour créer une liste mutable, si nécessaire:

 List places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata")); 

Des méthodes similaires sont disponibles pour Set et Map .

 List names = Arrays.asList("2","@2234","21","11"); 

Vous pouvez utiliser StickyList de Cactoos :

 List names = new StickyList<>( "Scott Fitzgerald", "Fyodor Dostoyevsky" ); 

Essayez avec cette ligne de code:

 Collections.singletonList(provider) 

Oui, à l’aide des tableaux, vous pouvez initialiser la liste de tableaux sur une seule ligne,

 List strlist= Arrays.asList("aaa", "bbb", "ccc"); 

En Java, vous ne pouvez pas faire

 ArrayList places = new ArrayList( Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 

Comme cela a été souligné, vous devez effectuer une initialisation à double accolade:

 List places = new ArrayList() {{ add("x"); add("y"); }}; 

Mais cela peut vous obliger à append une annotation @SuppressWarnings("serial") ou à générer un UUID série qui est agaçant. De plus, la plupart des formateurs de code déballeront cela en plusieurs déclarations / lignes.

Sinon, vous pouvez faire

 List places = Arrays.asList(new Ssortingng[] {"x", "y" }); 

mais alors vous voudrez peut-être faire un @SuppressWarnings("unchecked") .

Toujours selon javadoc, vous devriez pouvoir faire ceci:

 List stooges = Arrays.asList("Larry", "Moe", "Curly"); 

Mais je ne peux pas le faire comstackr avec JDK 1.6.

 Collections.singletonList(messageBody) 

Si vous avez besoin d’avoir une liste d’ un article !

Les collections proviennent du package java.util .

Voici le code par AbacusUtil

 // ArrayList List list = N.asList("Buenos Aires", "Córdoba", "La Plata"); // HashSet Set set = N.asSet("Buenos Aires", "Córdoba", "La Plata"); // HashMap Map map = N.asMap("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3); // Or for Immutable List/Set/Map ImmutableList.of("Buenos Aires", "Córdoba", "La Plata"); ImmutableSet.of("Buenos Aires", "Córdoba", "La Plata"); ImmutableSet.of("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3); // The most efficient way, which is similar with Arrays.asList(...) in JDK. // but returns a flexible-size list backed by the specified array. List set = Array.asList("Buenos Aires", "Córdoba", "La Plata"); 

Déclaration: je suis le développeur d’AbacusUtil.

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, j’aimerais que vous fassiez référence à l’ initialisation de ArrayList

La meilleure façon de le faire:

 package main_package; import java.util.ArrayList; public class Stackkkk { public static void main(Ssortingng[] args) { ArrayList list = new ArrayList(); add(list, "1", "2", "3", "4", "5", "6"); System.out.println("I added " + list.size() + " element in one line"); } public static void add(ArrayList list,Object...objects){ for(Object object:objects) list.add(object); } } 

Créez simplement une fonction pouvant contenir autant d’éléments que vous le souhaitez et appelez-la pour les append sur une seule ligne.

Pourquoi ne pas faire une simple fonction utilitaire qui fait cela?

 static  ArrayList ll(A... a) { ArrayList l = new ArrayList(a.length); for (A x : a) l.add(x); return l; } 

ll ” signifie “liste littérale”.

 ArrayList places = ll("Buenos Aires", "Córdoba", "La Plata"); 

En fait, il est possible de le faire en une seule ligne:

 Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")}) 
 public static  List asList(T... a) { return new ArrayList(a); } 

Ceci est l’implémentation de Arrays.asList , donc vous pouvez aller avec

 ArrayList arr = (ArrayList) Arrays.asList("1", "2");