Question

Je souhaite 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 refactoré 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 faire cela?

Était-ce utile?

La solution

En fait, probablement le " meilleur " moyen d’initialiser la ArrayList est la méthode que vous avez écrite, car il n’est pas nécessaire de créer un nouveau List:

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

Le problème est qu’il faut pas mal de frappe pour se référer à 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 ")):

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

Cependant, je n'aime pas trop cette méthode, car vous obtenez une sous-classe de <=> qui a un initialiseur d'instance, et cette classe est créée uniquement pour créer un objet - cela ressemble à un peu exagéré pour moi.

Ce qui aurait été bien si les Littéraux de collection la proposition de Project Coin a été acceptée (elle devait être introduite dans Java 7, mais cela ne fera probablement pas partie de Java 8.):

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

Malheureusement, cela ne vous aidera pas ici, car il initialisera un <=> immuable plutôt qu'un <=>, et de plus, il n'est pas encore disponible, s'il le sera jamais.

Autres conseils

Ce serait plus simple si vous deviez simplement le déclarer comme un List - faut-il que ce soit un 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 places est immuable (essayer de le modifier provoquera la génération d'une exception UnsupportedOperationException).

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

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

La réponse simple

Sous Java 10, 11, 12 ou ultérieur:

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

Sous Java 9 ou version ultérieure:

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

Cela vous donnera un List immuable, 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:

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

Cela vous donnera un List.set supporté par le tableau, il ne peut donc pas changer de longueur.
Mais vous pouvez appeler Arrays.asList, il est donc toujours modifiable.

Vous pouvez rendre Alt+Enter encore plus court avec une importation statique:

List<String> strings = 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, vous appuyez sur Static import method... et sélectionnez List.of.

Cependant, je ne recommande pas de raccourcir la méthode Java 9 of, car avoir juste Stream devient déroutant.
java.util.ArrayList est déjà assez court et lit bien.

Utilisation de ArrayList s

Pourquoi faut-il que ce soit un Iterable?
Avec Java 8 ou version ultérieure, vous pouvez utiliser un Collection qui est plus flexible:

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

Vous pouvez concaténer LinkedList s:

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

Ou vous pouvez passer d'un Arrays.asList() à un void method(...):

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

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

Mais de préférence, utilisez simplement le InputStream sans le collecter vers un FileInputStream.

Si vous vraiment avez particulièrement besoin d'un BufferedInputStream

(Vous n'avez probablement pas.)
Pour citer PPC 269 ():

  

Il existe un petit ensemble de cas d'utilisation permettant d'initialiser une instance de collection modifiable 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 pré-remplir un ajout <=> et par la suite (pourquoi?), utilisez

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

ou dans Java 8 ou une version antérieure:

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

ou en utilisant <=>:

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 vaut mieux utiliser le <=> directement plutôt que de le collecter dans un <=>.

Programmez les interfaces et non les implémentations

Vous avez dit que vous avez déclaré la liste comme <=> dans votre code, mais vous ne devriez le faire que si vous utilisez un membre de <=> qui n'est pas dans <=>.

Ce que vous ne ferez probablement pas.

Habituellement, vous devez simplement déclarer les variables à l'aide de l'interface la plus générale que vous allez utiliser (par exemple, <=>, <=> ou <=>), puis les initialiser avec une implémentation spécifique (par exemple, <=>, < => ou <=>).

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

Par exemple, si vous passez un <=> à un <=>:

// 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 consisterait toujours à déclarer une variable <=> même s’il s’agit en général de <=> ou de <=>, car dans un jour prochain, vous ou une autre personne voudrez utiliser un autre type de <=>.

Si vous avez besoin d'une simple liste 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");

Avec Goyave , vous pouvez écrire:

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

Il existe également d’autres constructeurs statiques utiles dans Guava. Vous pouvez en savoir plus sur ici .

Les littéraux de collection n'ont pas été intégrés à Java 8, mais il est possible d'utiliser l'API Stream pour initialiser une liste sur une ligne plutôt 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));
import com.google.common.collect.ImmutableList;

....

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

Avec Java 9, comme suggéré dans la proposition d'amélioration du JDK - 269 , cela pourrait être réalisé en utilisant les littéraux de collection maintenant -

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 à Proposition de collection Literals comme l'a déclaré @coobird également. De plus amples précisions dans le doc du PEC également -

Alternatives

  

Les modifications de langue ont été examinées à plusieurs reprises et rejetées:

     

Proposition de pièce de monnaie, 29 mars 2009

     

Proposition de pièce de monnaie, 30 mars 2009

     

Discussion sur le PEC 186 sur lambda-dev, janvier -Mars 2014

     

La langue   propositions ont été réservées de préférence à une proposition basée sur une bibliothèque   résumées dans ce message.

Related = > Qu'est-ce que c'est? le point de surcharge des méthodes Convenience Factory pour les collections en Java 9

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;
}

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. Immutabilité
  3. Coffre-fort aux threads

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

Avec les Collections Eclipse , vous pouvez écrire ce qui suit:

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

Vous pouvez également préciser les types et déterminer 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 la même chose 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 partisan des collections Eclipse.

La façon la plus compacte de procéder est la suivante:

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

Voici un autre moyen:

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

Utilisez simplement le code ci-dessous comme suit.

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

Vous pouvez utiliser les instructions ci-dessous:

Extrait de code:

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

List<String> names = Arrays.asList(arr);

(Doit ê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. De plus, il ne gère pas très bien l'héritage. Par exemple, supposons que vous ayez les éléments suivants:

class A{}
class B extends A{}

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

Ce qui précède génère une erreur de compilation, car List<B> (qui est renvoyé par Arrays.asList) n'est pas une sous-classe de List<A>, même si vous pouvez ajouter des objets de type B à un <=> objet. . Pour résoudre 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, en particulier. si vous avez besoin d'une liste illimitée ou devez utiliser l'héritage.

Comme Tom a déclaré :

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 puisse vous amener à vous plaindre de "performance".

Dans ce cas, cela n’a aucun sens pour moi, puisque votre liste est prédéfinie, elle n’a pas été définie comme un tableau (car sa 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 un 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 également 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 enum ensemble, ce qui nécessiterait une nouvelle compilation si la liste devait être modifiée à l'avenir.

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

deviendrait:

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 énumérations ont une méthode statique values qui renvoie un tableau contenant toutes les valeurs de l’énum 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 présenté un autre moyen intéressant d'utiliser la méthode de l'utilitaire statique Collections.addAll .

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

.
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"));

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

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

Vous pouvez utiliser StickyList à partir de Cactoos :

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

Essayez avec cette ligne de code:

Collections.singletonList(provider)

Oui, à l'aide de tableaux, vous pouvez initialiser la liste de tableaux sur une ligne,

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

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 devez effectuer une initialisation à double accolade:

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

Mais cela peut vous obliger à ajouter une annotation @SuppressWarnings("serial") ou à générer un UUID série ennuyeux. De plus, la plupart des formateurs de code décompressent cela en plusieurs instructions / lignes.

Sinon, vous pouvez faire

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

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

Selon javadoc, vous devriez également pouvoir le faire:

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

Mais je ne parviens pas à le compiler avec JDK 1.6.

Collections.singletonList(messageBody)

Si vous devez disposer d'une liste d'un élément !

Les

Collections proviennent du package java.util .

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 pouvant contenir autant d'éléments que vous le souhaitez et appelez-la pour les ajouter sur une seule ligne.

Voici le code généré 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 & # 65306; Je suis le développeur de AbacusUtil.

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

Pourquoi ne pas créer une fonction utilitaire simple qui le fasse?

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");

Je crée une liste de messageTemplate à partir d'un fichier XML stocké dans le chemin path précédent dans un contexte statique

public final class TemplateStore {

    private TemplateStore(){}

    private static final String [] VERSIONS = {"081"};
    private static final String TEMPLATE_FILE_MASK = "template/EdiTemplates_v%s.xml";
    private static final String ERROR = "Error In Building Edifact Message Template Store";

    public static final List<MessageTemplate> TEMPLATE_LIST = Arrays.stream(VERSIONS)
            .map(version -> TemplateStore.class
                    .getClassLoader().getResourceAsStream(String.format(TEMPLATE_FILE_MASK, version)))
            .map(inputStream -> {
                try {
                    return ((EdiTemplates) JAXBContext.newInstance(EdiTemplates.class).createUnmarshaller()
                            .unmarshal(inputStream)).getMessageTemplate();
                } catch (JAXBException e) {
                    throw new IllegalArgumentException(ERROR, e);
                }})
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
}

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

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top