web-dev-qa-db-fra.com

Collections.emptyList () vs nouvelle instance

En pratique, vaut-il mieux renvoyer une liste vide comme this :

return Collections.emptyList();

Ou comme this :

return new ArrayList<Foo>();

Ou cela dépend-il complètement de ce que vous allez faire avec la liste renvoyée?

223
mre

La principale différence est que Collections.emptyList() renvoie une liste immutable, c’est-à-dire une liste à laquelle vous ne pouvez pas ajouter d’éléments. (Même chose pour le List.of() introduit dans Java 9.)

Dans les rares cas où vous do souhaitez modifier la liste renvoyée, Collections.emptyList() et List.of() sont donc et non un bon choix.

Je dirais que renvoyer une liste immuable est parfaitement correct (et même le moyen préféré) tant que le contrat (documentation) ne stipule pas explicitement différemment.


De plus, emptyList()pourrait ne pas créer un nouvel objet à chaque appel.

Les implémentations de cette méthode n'ont pas besoin de créer un objet List distinct pour chaque appel. L'utilisation de cette méthode est susceptible d'avoir un coût comparable à l'utilisation du champ portant le même nom. (Contrairement à cette méthode, le champ ne fournit pas de sécurité de type.)

L'implémentation de emptyList se présente comme suit:

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

Ainsi, si votre méthode (qui renvoie une liste vide) est appelée très souvent, cette approche peut même vous donner des performances légèrement meilleures, tant en termes de processeur que de mémoire.

278
aioobe

À partir de Java 5.0, vous pouvez spécifier le type d'élément dans le conteneur:

Collections.<Foo>emptyList()

Je conviens avec les autres réponses que, dans les cas où vous souhaitez renvoyer une liste vide qui reste vide, vous devez utiliser cette approche.

50
Paul Jackson

Collections.emptyList est immuable, il existe donc une différence entre les deux versions. Vous devez donc prendre en compte les utilisateurs de la valeur renvoyée.

Renvoyer new ArrayList<Foo> crée toujours une nouvelle instance de l'objet, ce qui entraîne un très léger surcoût, ce qui peut vous donner une raison d'utiliser Collections.emptyList. J'aime utiliser emptyList simplement parce que c'est plus lisible.

27
Jeff Foster

Soyez prudent cependant. Si vous retournez Collections.emptyList() et essayez ensuite d'y apporter des modifications telles que add() ou ainsi, u aura un UnsupportedOperationException() car Collections.emptyList() renvoie un objet immuable.

13
mrserfr

J'irais avec Collections.emptyList() si la liste renvoyée n'est modifiée d'aucune manière (car la liste est immuable), sinon j'opterais pour l'option 2.

L'avantage de Collections.emptyList() est que la même instance statique est renvoyée à chaque fois et qu'il n'y a donc pas de création d'instance pour chaque appel.

7
S73417H

Utilisez Collections.emptyList () si vous voulez vous assurer que la liste renvoyée n'est jamais modifiée. Voici ce qui est retourné lors de l'appel de emptyList ():

/**
 * The empty list (immutable). 
 */
public static final List EMPTY_LIST = new EmptyList();
3
Atul

Les réponses données soulignent le fait que emptyList() renvoie un List immuable, mais n'offrent pas d'alternatives. Le constructeur ArrayList(int initialCapacity) cas spéciaux 0 renvoyant ainsi new ArrayList<>(0) au lieu de new ArrayList<>() pourrait également être une solution viable:

/**
 * Shared empty array instance used for empty instances.
 */
private static final Object[] EMPTY_ELEMENTDATA = {};

[...]

/**
 * Constructs an empty list with the specified initial capacity.
 *
 * @param  initialCapacity  the initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

(sources de Java 1.8.0_72)

2
René