web-dev-qa-db-fra.com

Définir une liste de taille fixe en Java

Est-il possible de définir une liste avec une taille fixe de 100? Sinon pourquoi n'est-ce pas disponible en Java?

37
fastcodejava

Oui,

Commons library fournit un FixedSizeList qui ne prend pas en charge les méthodes add, remove et clear (mais la méthode set est autorisée car elle ne modifie pas la taille de List En d'autres termes, si vous essayez d'appeler l'une de ces méthodes, votre liste conserve la même taille.

Pour créer votre liste de taille fixe, appelez simplement

List<YourType> fixed = FixedSizeList.decorate(Arrays.asList(new YourType[100]));

Vous pouvez utiliser unmodifiableList si vous souhaitez une vue non modifiable de la liste spécifiée ou un accès en lecture seule aux listes internes.

List<YourType> unmodifiable = Java.util.Collections.unmodifiableList(internalList);
17
Arthur Ronald

Cela devrait le faire si la mémoire sert:

List<MyType> fixed = Arrays.asList(new MyType[100]);
33
McDowell

Soit votre question est erronée, soit vous avez un modèle mental incorrect de ce qu'est un Java List.


Une liste Java est une collection d'objets, les éléments d'une liste. La taille de la liste est le nombre d'éléments de cette liste. Si vous souhaitez que cette taille soit corrigée, cela signifie que vous ne pouvez ni ajouter ni supprimer des éléments, car l’ajout ou la suppression d’éléments violerait votre contrainte de "taille fixe".

Le moyen le plus simple d'implémenter une liste "de taille fixe" (si c'est vraiment ce que vous voulez!) Consiste à placer les éléments dans un tableau, puis à Arrays.asList(array) pour créer le gestionnaire de liste. Le wrapper vous permettra de faire des opérations comme get et set, mais les opérations add et remove lèveront des exceptions.

Et si vous souhaitez créer un wrapper de taille fixe pour une liste existante, vous pouvez utiliser Apache commons FixedSizeList class. Cependant, notez que ce wrapper ne peut pas empêcher quelque chose d'autre de changer la taille de la liste d'origine, et si cela se produit, la liste renvoyée reflétera vraisemblablement ces modifications. (IMO, le javadoc pour FixedSizeList est lamentable. Il ne tente en aucun cas de décrire le comportement de la classe lorsque la liste renvoyée est modifiée. Vous devrez lire le code source ne font pas attention.)


D'autre part, si vous voulez vraiment un type de liste avec une limite fixe (ou des limites) sur sa taille, vous devrez créer votre propre classe List pour l'implémenter. Par exemple, vous pouvez créer une classe wrapper qui implémente les contrôles pertinents dans les différentes opérations add/addAll et remove/removeAll/retainAll. (Et dans les méthodes itérateur remove si elles sont prises en charge.)

Alors, pourquoi le framework Java Collections ne les implémente-t-il pas? Voici pourquoi je pense que oui:

  1. Les cas d'utilisation qui en ont besoin sont rares.
  2. Dans les cas d'utilisation où cela est nécessaire, il y a des exigences différentes sur ce qu'il faut faire lorsqu'une opération tente de dépasser les limites; par exemple. jeter une exception, ignorer l'opération, ignorer un autre élément pour libérer de l'espace.
  3. Une implémentation de liste avec des limites pourrait être problématique pour les méthodes auxiliaires; par exemple. Collections.sort.
27
Stephen C

Oui. Vous pouvez passer un tableau Java à Arrays.asList (Object []) .

List<String> fixedSizeList = Arrays.asList(new String[100]);

Vous ne pouvez pas insérer de nouvelles chaînes dans la liste fixedSizeList (celle-ci contient déjà 100 éléments). Vous pouvez uniquement définir ses valeurs comme ceci:

fixedSizeList.set(7, "new value");

De cette façon, vous avez une liste de taille fixe. La chose fonctionne comme un tableau et je ne peux pas penser à une bonne raison de l’utiliser. J'aimerais savoir pourquoi vous voulez que votre collection de taille fixe soit une liste plutôt que d'utiliser simplement un tableau.

12
snakile

En règle générale, les tableaux Java sont une alternative aux listes de taille fixe. Les listes par défaut sont autorisées à grossir/réduire en Java. Toutefois, cela ne signifie pas que vous ne pouvez pas avoir une liste de taille fixe. Vous devrez travailler et créer une implémentation personnalisée.

Vous pouvez étendre un ArrayList avec des implémentations personnalisées des méthodes clear, add et remove.

par exemple.

import Java.util.ArrayList;

public class FixedSizeList<T> extends ArrayList<T> {

    public FixedSizeList(int capacity) {
        super(capacity);
        for (int i = 0; i < capacity; i++) {
            super.add(null);
        }
    }

    public FixedSizeList(T[] initialElements) {
        super(initialElements.length);
        for (T loopElement : initialElements) {
            super.add(loopElement);
        }
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("Elements may not be cleared from a fixed size List.");
    }

    @Override
    public boolean add(T o) {
        throw new UnsupportedOperationException("Elements may not be added to a fixed size List, use set() instead.");
    }

    @Override
    public void add(int index, T element) {
        throw new UnsupportedOperationException("Elements may not be added to a fixed size List, use set() instead.");
    }

    @Override
    public T remove(int index) {
        throw new UnsupportedOperationException("Elements may not be removed from a fixed size List.");
    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException("Elements may not be removed from a fixed size List.");
    }

    @Override
    protected void removeRange(int fromIndex, int toIndex) {
        throw new UnsupportedOperationException("Elements may not be removed from a fixed size List.");
    }
}
8
shams

Créez un tableau de taille 100. Si vous avez besoin de l'interface List, appelez Arrays.asList . Cela retournera une liste de taille fixe soutenue par le tableau.

3

Si vous voulez plus de flexibilité, créez une classe qui surveille la taille de la liste.

Voici un exemple simple. Vous devez remplacer toutes les méthodes qui modifient l'état de la liste.

public class LimitedArrayList<T> extends ArrayList<T>{
    private int limit;

    public LimitedArrayList(int limit){
        this.limit = limit;
    }

    @Override
    public void add(T item){
        if (this.size() > limit)
            throw new ListTooLargeException();
        super.add(item);
    }

    // ... similarly for other methods that may add new elements ...
2
Jeremy

Si vous voulez utiliser ArrayList ou LinkedList , il semble que la réponse soit non. Bien que certaines classes de Java permettent de définir une taille fixe, comme PriorityQueue , ArrayList et LinkedList ne le peuvent pas, car il n’existe aucun constructeur pour spécifier la capacité.

Si vous souhaitez vous en tenir à ArrayList/LinkedList, une solution simple consiste à vérifier la taille manuellement à chaque fois.

public void fixedAdd(List<Integer> list, int val, int size) {
    list.add(val);
    if(list.size() > size) list.remove(0);
}

LinkedList est meilleur que ArrayList dans cette situation. Supposons qu'il y ait beaucoup de valeurs à ajouter mais que la taille de la liste soit assez petite, il y aura beaucoup d'opérations de suppression. La raison en est que le coût de suppression de ArrayList est de O (N), mais seulement O(1) pour LinkedList.

0
Jacky Wang