Initialisation d'une ArrayList sur une ligne


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

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 façon de le faire?

Author: Shashanth, 2009-06-17

30 answers

En Fait, probablement la "meilleure" façon d'initialiser le ArrayList est la méthode que vous avez écrit, comme il n'a pas besoin de créer un nouveau List, en quelque sorte:

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

Le problème est qu'il y a un peu de frappe nécessaire pour se référer à cette instance list.

Il existe des alternatives, telles que la création d'une classe interne anonyme avec un initialiseur d'instance (également connu sous le nom d '"initialisation à double accolade"):

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

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

Ce qui aurait été bien, c'est si la proposition Collection Literalspour Project Coin était acceptée (elle devait être introduite dans Java 7, mais elle ne devrait pas non plus faire partie de Java 8.):

List<String> list = ["A", "B", "C"];

Malheureusement, cela ne vous aidera pas ici, car il initialisera un List immuable plutôt que an ArrayList, et de plus, il n'est pas encore disponible, s'il le sera un jour.

 2116
Author: coobird, 2015-03-13 15:27:35

Ce serait plus simple si vous deviez simplement le déclarer comme un List - doit-il être une ArrayList?

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

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

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

Cela signifierait que placesest immuable (essayer de le changer entraînera la levée d'une exception UnsupportedOperationException).

Pour faire une mutable liste qui est un béton ArrayList, vous pouvez créer un ArrayList à partir de la liste immuable:

ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
 2253
Author: Tom, 2016-06-16 21:38:30

La réponse simple

Dans Java 9, ou plus tard, après List.of() a été ajouté:

List<String> strings = List.of("foo", "bar", "baz");

Avec Java 10 ou version ultérieure, cela peut être raccourci avec le mot-clé var.

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

Cela vous donnera une immuable List, il ne peut donc pas être changé.
C'est ce que vous voulez dans la plupart des cas où vous le prépeuplez.


Java 8 ou version antérieure:

List<String> strings = Arrays.asList("foo", "bar", "baz");

Cela vous donnera un List soutenu par un tableau, donc il ne peut pas changer longueur.
Mais vous pouvez appeler List.set, donc c'est toujours mutable.


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

List<String> strings = asList("foo", "bar", "baz");

L'importation statique:

import static java.util.Arrays.asList;  

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


Cependant, je ne recommande pas de raccourcir la méthode List.of à of, car cela devient déroutant.
List.of est déjà assez court et se lit bien.


En utilisant Stream s

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

Stream<String> strings = Stream.of("foo", "bar", "baz");

, Vous pouvez concaténer Streams:

Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
                                       Stream.of("baz", "qux"));

Ou vous pouvez passer d'un Stream à un List:

import static java.util.stream.Collectors.toList;

List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());

, Mais de préférence, il suffit d'utiliser le Stream, sans collecte à un List.


{Si vous[62]}vraiment spécifiquement besoin d'un java.util.ArrayList

(Vous ne le faites probablement pas.)
Pour citer JEP 269 (emphase à moi):

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


Si vous voulez deux préremplir un ArrayList et ajouter par la suite (pourquoi?), utiliser

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

Ou en Java 8 ou plus tôt:

ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");

Ou en utilisant Stream:

import static java.util.stream.Collectors.toCollection;

ArrayList<String> strings = Stream.of("foo", "bar")
                             .collect(toCollection(ArrayList::new));
strings.add("baz");

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


Programme aux interfaces, pas aux implémentations

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

Ce que vous ne faites probablement pas.

Habituellement, vous devez simplement déclarer les variables par le plus interface générale que vous allez utiliser (par exemple Iterable, Collection, ou List), et initialisez-les 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 changer quand vous le souhaitez.

Par exemple, si vous passez un ArrayList à un void method(...):

// Iterable if you just need iteration, for (String s : strings):
void method(Iterable<String> strings) { 
    for (String s : strings) { ... } 
}

// Collection if you also need .size(), .isEmpty(), or .stream():
void method(Collection<String> strings) {
    if (!strings.isEmpty()) { strings.stream()... }
}

// List if you also need .get(index):
void method(List<String> strings) {
    strings.get(...)
}

// Don't declare a specific list implementation
// unless you're sure you need it:
void method(ArrayList<String> strings) {
    ??? // You don't want to limit yourself to just ArrayList
}

Un autre exemple serait toujours de déclarer une variable an InputStream même si elle est généralement un FileInputStream ou un BufferedInputStream, car bientôt, vous ou quelqu'un d'autre voudrez utiliser un autre type de InputStream.

 929
Author: Christoffer Hammarström, 2020-06-20 09:12:55

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

List<String> strings = new ArrayList<String>(Collections.singletonList("A"));

Si vous avez besoin d'une liste de plusieurs objets:

List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");
 113
Author: Randyaa, 2017-05-27 21:31:06

Avec Goyave, vous pouvez écrire:

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

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

 57
Author: Paweł Adamski, 2017-12-12 03:02:22

Avec java-9 et au-dessus, comme suggéré dans JEP 269: Convenience Factory Methods for Collections, cela pourrait être réalisé en utilisant collection literals maintenant avec -

List<String> list = List.of("A", "B", "C");

Set<String> set = Set.of("A", "B", "C");

Une approche similaire s'appliquerait également à Map -

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

, Qui est similaire à Collection de Littéraux proposition comme indiqué par @coobird. Clarifié également dans le PEC-


Solutions de rechange

Les changements de langue ont été pris en compte plusieurs fois, et rejeté:

Projet de pièce de monnaie, 29 mars 2009

Projet de pièce de monnaie, 30 mars 2009

JEP 186 discussion sur lambda-dev, janvier-mars 2014

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

Related: Quel est l'intérêt des méthodes d'usine de commodité surchargées pour les Collections dans Java 9

 43
Author: Naman, 2020-06-20 09:12:55

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 assez longue:

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

Si vous devez vous assurer que votre List est un ArrayList:

ArrayList<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new));
 34
Author: Mark, 2014-04-03 23:21:48
import com.google.common.collect.ImmutableList;

....

List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
 31
Author: George, 2010-05-12 13:14:16

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

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

....

ArrayList<String> 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 <T> ArrayList<T> createArrayList(T ... elements) {
  ArrayList<T> list = new ArrayList<T>();
  for (T element : elements) {
    list.add(element);
  }
  return list;
}
 24
Author: Jordão, 2018-03-04 21:29:06

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

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

Ou

List<String> 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édentes:

  1. Efficacité spatiale
  2. l'Immutabilité
  3. Fil sûr

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

 16
Author: Mohit Tyagi, 2018-03-04 22:29:01

À propos de la façon la plus compacte de le faire est:

Double array[] = { 1.0, 2.0, 3.0};
List<Double> list = Arrays.asList(array);
 8
Author: Richard B, 2014-12-15 11:44:15

Utilisez simplement le code ci-dessous comme suit.

List<String> list = new ArrayList<String>() {{
            add("A");
            add("B");
            add("C");
}};
 8
Author: user2801794, 2017-12-12 02:57:48

Avec Eclipse Collections vous pouvez écrire ce qui suit:

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

Vous pouvez également être plus précis sur les types et s'ils sont Mutables ou Immuables.

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

Vous pouvez également faire de même avec des ensembles et des sacs:

Set<String> set = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableSet<String> mSet = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet<String> iSet = Sets.immutable.with("Buenos Aires", "Córdoba", "La Plata");

Bag<String> bag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableBag<String> mBag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableBag<String> iBag = Bags.immutable.with("Buenos Aires", "Córdoba", "La Plata");

Remarque: Je suis un committer pour les collections Eclipse.

 8
Author: Donald Raab, 2019-05-01 01:53:10

Voici une autre façon:

List<String> values = Stream.of("One", "Two").collect(Collectors.toList());
 7
Author: Henok T, 2017-03-01 00:49:20

(Devrait être un commentaire, mais trop long, donc nouvelle réponse). Comme d'autres l'ont mentionné, la méthode Arrays.asList est de taille fixe, mais ce n'est pas le seul problème avec elle. Il ne gère pas non plus très bien l'héritage. Par exemple, supposons que vous ayez ce qui suit:

class A{}
class B extends A{}

public List<A> getAList(){
    return Arrays.asList(new B());
}

Ce qui précède entraîne une erreur du compilateur, car List<B> (qui est ce qui est renvoyé par les tableaux.asList) n'est pas une sous-classe de List<A>, même si vous pouvez ajouter des objets de type B à un objet List<A>. Pour contourner ce problème, vous devez faire quelque chose comme:

new ArrayList<A>(Arrays.<A>asList(b1, b2, b3))

C'est probablement la meilleure façon de procéder, esp. si vous avez besoin d'une liste illimitée ou que vous devez utiliser l'héritage.

 7
Author: user439407, 2017-12-12 02:57:07

Vous pouvez utiliser les instructions ci-dessous:

Extrait de code:

String [] arr = {"Sharlock", "Homes", "Watson"};

List<String> names = Arrays.asList(arr);
 6
Author: rashedcs, 2020-06-20 09:12:55

Comme Tom a dit:

List<String> 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 vous pouvez simplement ajouter cette ligne:

ArrayList<String> myPlaces = new ArrayList(places);

Bien que, cela pourrait vous faire vous plaindre de "performance".

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 (puisque la taille est connue au moment de l'initialisation). Et si c'est une option pour vous:

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

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

ArrayList<String> myPlaces = new ArrayList(Arrays.asList(places));

D'accord, mais à l'avenir, vous avez besoin d'un peu plus que le nom du lieu, vous avez aussi besoin d'un code de pays. En supposant qu'il s'agisse toujours d'une liste prédéfinie qui ne changera jamais pendant l'exécution, il convient d'utiliser un ensemble enum, qui nécessiterait une re-compilation si la liste devait être modifiée à l'avenir.

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

Serait devenir:

enum Places {
    BUENOS_AIRES("Buenos Aires",123),
    CORDOBA("Córdoba",456),
    LA_PLATA("La Plata",789);

    String name;
    int code;
    Places(String name, int code) {
      this.name=name;
      this.code=code;
    }
}
Les

Enum ont une méthode statique values qui renvoie un tableau contenant toutes les valeurs de l'énumération dans l'ordre dans lequel 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.

P.S.Randyaa a démontré une autre bonne façon d'utiliser la méthode utilitaire statique Collections.addAll .

 5
Author: Ozzy, 2017-05-23 12:10:48

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

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

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

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

Méthodes Similaires sont disponibles pour les Set et Map.

 5
Author: user85421, 2016-12-06 09:57:49
List<String> names = Arrays.asList("2","@2234","21","11");
 4
Author: Ran Adler, 2015-09-23 13:18:51

Oui, avec l'aide de Tableaux vous pouvez initialiser la liste en une seule ligne,

List<String> strlist= Arrays.asList("aaa", "bbb", "ccc");
 4
Author: Akash Manngroliya, 2016-09-13 05:54:55

Vous pouvez utiliser StickyList à partir de Cactoos:

List<String> names = new StickyList<>(
  "Scott Fitzgerald", "Fyodor Dostoyevsky"
);
 4
Author: yegor256, 2017-06-25 17:48:17

Essayez avec cette ligne de code:

Collections.singletonList(provider)
 3
Author: Ant20, 2016-05-16 14:25:18

En Java, vous ne pouvez pas faire

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

Comme cela a été souligné, vous devrez faire une double initialisation d'accolade:

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

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éballeront cela en plusieurs instructions/lignes.

Alternativement, vous pouvez faire

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

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

Toujours selon javadoc, vous devriez pouvoir le faire:

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

Mais je ne suis pas capable de le faire compiler avec JDK 1.6.

 2
Author: Dawg, 2012-02-13 22:44:20
Collections.singletonList(messageBody)

Si vous auriez besoin d'avoir une liste de un élément de!

Les collections proviennent de java.util paquet.

 1
Author: ViliusK, 2015-04-03 09:30:38

La meilleure façon de le faire:

package main_package;

import java.util.ArrayList;


public class Stackkkk {
    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<Object>();
        add(list, "1", "2", "3", "4", "5", "6");
        System.out.println("I added " + list.size() + " element in one line");
    }

    public static void add(ArrayList<Object> list,Object...objects){
        for(Object object:objects)
            list.add(object);
    }
}

Créez simplement une fonction qui peut avoir autant d'éléments que vous le souhaitez et appelez-la pour les ajouter en une seule ligne.

 1
Author: Charif DZ, 2017-05-27 21:35:25

Voici le code par AbacusUtil

// ArrayList
List<String> list = N.asList("Buenos Aires", "Córdoba", "La Plata");
// HashSet
Set<String> set = N.asSet("Buenos Aires", "Córdoba", "La Plata");
// HashMap
Map<String, Integer> 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<String> set = Array.asList("Buenos Aires", "Córdoba", "La Plata");

Déclaration: Je suis le développeur de AbacusUtil.

 1
Author: user_3380739, 2019-01-27 22:46:36

Pour moi Tableaux.asList () est le meilleur et pratique. J'aime toujours initialiser cette façon. Si vous êtes un débutant dans les collections Java, j'aimerais que vous référiez à ArrayList initialization

 0
Author: Manoj Kumar, 2014-12-07 05:37:12

Pourquoi ne pas créer une simple fonction utilitaire qui fait cela?

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

"ll" signifie "liste littérale".

ArrayList<String> places = ll("Buenos Aires", "Córdoba", "La Plata");
 0
Author: Stefan Reich, 2017-12-04 11:23:08

fait intéressant, personne-liner avec l'autre surchargé Stream::collect la méthode est listée

ArrayList<String> places = Stream.of( "Buenos Aires", "Córdoba", "La Plata" ).collect( ArrayList::new, ArrayList::add, ArrayList::addAll );
 0
Author: Kaplan, 2019-10-04 15:04:11

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

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})
 -1
Author: Adrian, 2017-05-27 21:31:36