Java ArrayList comment ajouter des éléments au début


183

J'ai besoin d'ajouter des éléments à une ArrayListfile d' attente, mais quand j'appelle la fonction pour ajouter un élément, je veux qu'elle ajoute l'élément au début du tableau (il a donc l'indice le plus bas) et si le tableau a 10 éléments ajoutant un nouveau entraîne la suppression de l'élément le plus ancien (celui avec l'indice le plus élevé).

Est-ce que quelqu'un a des suggestions?


Voulez-vous dire comme removeet add?
Peter Lawrey

Il arraylist stack queue whatevervaut mieux éviter ce que vous utilisez pour ajouter au début d'un tableau et il semble que vous devriez utiliser une collection différente.
Peter Lawrey

Tout d'abord, vous devez créer quelque chose vous-même. Qu'avez-vous fait jusqu'à présent?
Yegoshin Maxim

Réponses:


301

Lista la méthode add(int, E), vous pouvez donc utiliser:

list.add(0, yourObject);

Ensuite, vous pouvez supprimer le dernier élément avec:

if(list.size() > 10)
    list.remove(list.size() - 1);

Cependant, vous voudrez peut-être repenser vos besoins ou utiliser une structure de données différente, comme un Queue

ÉDITER

Jetez peut-être un œil à Apache CircularFifoQueue:

CircularFifoQueue est une file d'attente premier entré, premier sorti avec une taille fixe qui remplace son élément le plus ancien s'il est plein.

Initialisez-le simplement avec votre taille maximale:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
Je ne toucherais à aucune bibliothèque Apache avec un poteau de dix pieds, d'autant plus que les classes de collection de goyave existent. EvictingQueue de Guava pourrait être un bon choix ici.
DPM

26

Utilisation de structures de données spécifiques

Il existe différentes structures de données qui sont optimisées pour ajouter des éléments au premier index. Cependant, sachez que si vous convertissez votre collection en l'un de ces éléments, la conversation nécessitera probablement une complexité temporelle et spatiale deO(n)

Deque

Le JDK comprend la Dequestructure qui offre des méthodes comme addFirst(e)etofferFirst(e)

Deque<String> deque = new LinkedList<>();
deque.add("two");
deque.add("one");
deque.addFirst("three");
//prints "three", "two", "one"

Une analyse

La complexité spatiale et temporelle de l'insertion est avec la LinkedListconstante ( O(1)). Voir la feuille de triche Big-O .

Inverser la liste

Une méthode très simple mais inefficace consiste à utiliser l'inverse:

 Collections.reverse(list);
 list.add(elementForTop);
 Collections.reverse(list);

Si vous utilisez des flux Java 8, cette réponse pourrait vous intéresser.

Une analyse

  • Complexité temporelle: O(n)
  • Complexité de l'espace: O(1)

En regardant l' implémentation JDK, cela a une O(n)complexité temporelle et ne convient donc qu'aux très petites listes.


Inverser une liste deux fois. Ajoutera-t-il le temps d'exécution de l'algorithme par une grande marge par rapport à la solution acceptée ci-dessus?
Samyak Upadhyay

Cela ajoute 2n, donc oui, mais si vous avez une liste de <50, vous ne seriez pas en mesure de micro-benchmarker la différence sur la plupart des machines modernes
Patrick Favre

8

Vous pouvez jeter un oeil à l' ajout (index int, élément E) :

Insère l'élément spécifié à la position spécifiée dans cette liste. Décale l'élément actuellement à cette position (le cas échéant) et les éléments suivants vers la droite (en ajoute un à leurs indices).

Une fois que vous l'avez ajouté, vous pouvez vérifier la taille de la ArrayList et supprimer celles à la fin.


4

Vous voudrez peut-être regarder Deque. il vous donne un accès direct au premier et au dernier élément de la liste.


1
Je suis surpris que vous soyez la seule réponse en parlant de Deque, c'est évidemment la meilleure solution optimale.
Guillaume F.

3

Ce que vous décrivez est une situation appropriée à utiliser Queue.

Puisque vous voulez un addnouvel élément, et removel'ancien. Vous pouvez ajouter à la fin et supprimer depuis le début. Cela ne fera pas beaucoup de différence.

La file d'attente a des méthodes add(e)et remove()qui ajoute à la fin le nouvel élément, et supprime depuis le début l'ancien élément, respectivement.

Queue<Integer> queue = new LinkedList<Integer>();
queue.add(5);
queue.add(6);
queue.remove();  // Remove 5

Ainsi, chaque fois que vous ajoutez un élément au, queuevous pouvez le sauvegarder avec un removeappel de méthode.


MISE À JOUR : -

Et si vous souhaitez fixer la taille duQueue , vous pouvez jeter un oeil à: -ApacheCommons#CircularFifoBuffer

Du documentation: -

CircularFifoBuffer est un premier tampon entré, premier sorti avec une taille fixe qui remplace son élément le plus ancien s'il est plein.

Buffer queue = new CircularFifoBuffer(2); // Max size

queue.add(5);
queue.add(6);
queue.add(7);  // Automatically removes the first element `5`

Comme vous pouvez le voir, lorsque la taille maximale est atteinte, l'ajout d'un nouvel élément supprime automatiquement le premier élément inséré.


1

Je pense que la mise en œuvre devrait être facile, mais compte tenu de l'efficacité, vous devriez utiliser LinkedList mais pas ArrayList comme conteneur. Vous pouvez vous référer au code suivant:

import java.util.LinkedList;
import java.util.List;

public class DataContainer {

    private List<Integer> list;

    int length = 10;
    public void addDataToArrayList(int data){
        list.add(0, data);
        if(list.size()>10){
            list.remove(length);
        }
    }

    public static void main(String[] args) {
        DataContainer comp = new DataContainer();
        comp.list = new LinkedList<Integer>();

        int cycleCount = 100000000;

        for(int i = 0; i < cycleCount; i ++){
            comp.addDataToArrayList(i);
        }
    }
}


0

vous pouvez utiliser ce code

private List myList = new ArrayList();
private void addItemToList(Object obj){
    if(myList.size()<10){
      myList.add(0,obj);
    }else{
      myList.add(0,obj);
      myList.remove(10);
    }
}

0

Vous pouvez utiliser des méthodes de liste, supprimer et ajouter

list.add(lowestIndex, element);
list.remove(highestIndex, element);

0

Prenons cet exemple: -

List<String> element1 = new ArrayList<>();
element1.add("two");
element1.add("three");
List<String> element2 = new ArrayList<>();
element2.add("one");
element2.addAll(element1);

-1

Vous pouvez utiliser

public List<E> addToListStart(List<E> list, E obj){
list.add(0,obj);
return (List<E>)list;

}

Changer E avec votre type de données

Si la suppression de l'élément le plus ancien est nécessaire, vous pouvez ajouter:

list.remove(list.size()-1); 

avant la déclaration de retour. Sinon, la liste ajoutera votre objet au début et conservera également l'élément le plus ancien.

Cela supprimera le dernier élément de la liste.


-1
import java.util.*:
public class Logic {
  List<String> list = new ArrayList<String>();
  public static void main(String...args) {
  Scanner input = new Scanner(System.in);
    Logic obj = new Logic();
      for (int i=0;i<=20;i++) {
        String string = input.nextLine();
        obj.myLogic(string);
        obj.printList();
      }
 }
 public void myLogic(String strObj) {
   if (this.list.size()>=10) {
      this.list.remove(this.list.size()-1);
   } else {
     list.add(strObj); 
   }
 }
 public void printList() {
 System.out.print(this.list);
 }
}

-2

J'ai eu un problème similaire, en essayant d'ajouter un élément au début d'un tableau existant, de déplacer les éléments existants vers la droite et de supprimer le plus ancien (tableau [longueur-1]). Ma solution n'est peut-être pas très performante, mais elle fonctionne pour mes besoins.

 Method:

   updateArray (Element to insert)

     - for all the elements of the Array
       - start from the end and replace with the one on the left; 
     - Array [0] <- Element

Bonne chance

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.