Java ArrayList come aggiungere elementi all'inizio


183

Devo aggiungere elementi a una ArrayListcoda qualunque, ma quando chiamo la funzione per aggiungere un elemento, voglio che aggiunga l'elemento all'inizio dell'array (quindi ha l'indice più basso) e se l'array ha 10 elementi aggiungendo un nuovo comporta l'eliminazione dell'elemento più vecchio (quello con l'indice più alto).

Qualcuno ha qualche suggerimento?


Intendi come removee add?
Peter Lawrey,

Quello che stai usando arraylist stack queue whateverper aggiungerlo all'inizio di un array è meglio evitarlo e sembra che dovresti usare una raccolta diversa.
Peter Lawrey,

Innanzitutto, dovresti creare qualcosa da solo. Cosa hai fatto fino ad ora?
Yegoshin Maxim,

Risposte:


301

Listha il metodo add(int, E), quindi puoi usare:

list.add(0, yourObject);

Successivamente puoi eliminare l'ultimo elemento con:

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

Tuttavia, potresti voler ripensare i tuoi requisiti o utilizzare una diversa struttura di dati, come un Queue

MODIFICARE

Forse dai un'occhiata ad Apache CircularFifoQueue:

CircularFifoQueue è una coda first-in first-out con una dimensione fissa che sostituisce il suo elemento più vecchio se pieno.

Basta inizializzarlo con te dimensione massima:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
Non toccherei nessuna biblioteca apache con un palo da dieci piedi, soprattutto perché esistono le classi di raccolta di guava. Guava's EvictingQueue potrebbe essere una buona scelta qui.
DPM,

26

Utilizzo di specifiche strutture dati

Esistono varie strutture dati ottimizzate per l'aggiunta di elementi al primo indice. Ricorda, tuttavia, che se converti la tua raccolta in una di queste, la conversazione avrà probabilmente bisogno di una complessità temporale e spazialeO(n)

deque

Il JDK include la Dequestruttura che offre metodi come addFirst(e)eofferFirst(e)

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

Analisi

La complessità di spazio e tempo dell'inserimento è con LinkedListcostante ( O(1)). Vedi il cheatsheet di Big-O .

Invertire l'elenco

Un metodo molto semplice ma inefficiente è usare il contrario:

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

Se usi stream Java 8, questa risposta potrebbe interessarti.

Analisi

  • Complessità temporale: O(n)
  • Complessità spaziale: O(1)

Guardando l' implementazione di JDK questo ha una O(n)complessità temporale quindi adatta solo per elenchi molto piccoli.


Invertire una lista due volte. Aggiungerà il tempo di esecuzione dell'algoritmo di un grande margine rispetto alla soluzione sopra accettata?
Samyak Upadhyay,

Aggiunge 2n, quindi sì, ma se si dispone di un elenco di <50 non si sarà in grado di eseguire il micro-benchmark della differenza sulla maggior parte delle macchine moderne
Patrick Favre,

8

Puoi dare un'occhiata all'aggiunta (indice int, elemento E) :

Inserisce l'elemento specificato nella posizione specificata in questo elenco. Sposta l'elemento attualmente in quella posizione (se presente) e tutti gli elementi successivi a destra (aggiunge uno ai loro indici).

Una volta aggiunto, è possibile quindi controllare le dimensioni dell'ArrayList e rimuovere quelle alla fine.


4

Potresti voler guardare Deque. ti dà accesso diretto sia al primo che all'ultimo elemento dell'elenco.


1
Sono sorpreso che tu sia l'unica risposta parlando di Deque, questa è ovviamente la migliore soluzione ottimale.
Guillaume F.,

3

Quello che stai descrivendo è una situazione appropriata da usare Queue.

Dal momento che vuoi addnuovo elemento, e removequello vecchio. È possibile aggiungere alla fine e rimuovere dall'inizio. Ciò non farà molta differenza.

La coda ha metodi add(e)e remove()che aggiunge alla fine il nuovo elemento e rimuove dall'inizio il vecchio elemento, rispettivamente.

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

Quindi, ogni volta che aggiungi un elemento a queuepuoi eseguirne il backup con una removechiamata di metodo.


AGGIORNAMENTO : -

E se vuoi correggere la dimensione delQueue , allora puoi dare un'occhiata a: -ApacheCommons#CircularFifoBuffer

Dal documentation: -

CircularFifoBuffer è un buffer first in first out con una dimensione fissa che sostituisce il suo elemento più vecchio se pieno.

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

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

Come puoi vedere, quando viene raggiunta la dimensione massima, l'aggiunta di un nuovo elemento rimuove automaticamente il primo elemento inserito.


1

Penso che l'attrezzo dovrebbe essere facile, ma considerando l'efficienza, dovresti usare LinkedList ma non ArrayList come contenitore. È possibile fare riferimento al seguente codice:

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

puoi usare questo codice

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

È possibile utilizzare i metodi di elenco, rimuovere e aggiungere

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

0

Prendi questo esempio: -

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

-1

Puoi usare

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

}

Cambia E con il tuo tipo di dati

Se è necessario eliminare l'elemento meno recente, è possibile aggiungere:

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

prima della dichiarazione di ritorno. Altrimenti l'elenco aggiungerà il tuo oggetto all'inizio e manterrà anche l'elemento più vecchio.

Ciò eliminerà l'ultimo elemento nell'elenco.


-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

Ho avuto un problema simile, cercando di aggiungere un elemento all'inizio di un array esistente, spostare gli elementi esistenti a destra e scartare quello più vecchio (array [lunghezza-1]). La mia soluzione potrebbe non essere molto performante ma funziona per i miei scopi.

 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

In bocca al lupo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.