Java ArrayList, jak dodawać elementy na początku


183

Muszę dodać elementy do ArrayListkolejki, cokolwiek, ale kiedy wywołuję funkcję, aby dodać element, chcę, aby dodała element na początku tablicy (więc ma najniższy indeks) i jeśli tablica ma 10 elementów dodawania nowy powoduje usunięcie najstarszego elementu (tego o najwyższym indeksie).

Czy ktoś ma jakieś sugestie?


Masz na myśli jak removei add?
Peter Lawrey,

Do czego używasz swojego arraylist stack queue whateverjako dodawania na początku tablicy, najlepiej unikać i wydaje się, że powinieneś używać innej kolekcji.
Peter Lawrey,

Po pierwsze, powinieneś sam coś zrobić. Co zrobiłeś do tej pory?
Yegoshin Maxim

Odpowiedzi:


301

Listma metodę add(int, E), więc możesz użyć:

list.add(0, yourObject);

Następnie możesz usunąć ostatni element za pomocą:

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

Możesz jednak przemyśleć swoje wymagania lub użyć innej struktury danych, np Queue

EDYTOWAĆ

Może spójrz na Apache CircularFifoQueue:

CircularFifoQueue jest kolejką pierwszy na wejściu, pierwszy wyszedł, o stałym rozmiarze, który zastępuje najstarszy element, jeśli jest pełny.

Po prostu zainicjuj go maksymalnym rozmiarem:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
Nie dotykałbym żadnej biblioteki Apaczów dziesięciostopowym tyczkiem, zwłaszcza że istnieją klasy kolekcji guawy. Guava's EvictingQueue może być tutaj dobrym wyborem.
DPM,

26

Korzystanie z określonych struktur danych

Istnieją różne struktury danych, które są zoptymalizowane pod kątem dodawania elementów w pierwszym indeksie. Pamiętaj jednak, że jeśli przekonwertujesz swoją kolekcję na jedną z nich, rozmowa będzie prawdopodobnie wymagała złożoności czasowej i przestrzennejO(n)

Deque

JDK zawiera Dequestrukturę, która oferuje metody takie jak addFirst(e)iofferFirst(e)

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

Analiza

Złożoność przestrzenno-czasowa wstawiania jest LinkedListstała ( O(1)). Zobacz ściągawkę Big-O .

Odwracanie listy

Bardzo prostą, ale nieefektywną metodą jest użycie odwrotności:

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

Jeśli korzystasz ze strumieni Java 8, ta odpowiedź może Cię zainteresować.

Analiza

  • Złożoność czasowa: O(n)
  • Złożoność przestrzeni: O(1)

Patrząc na implementację JDK, jest to O(n)skomplikowane czasowo, więc nadaje się tylko do bardzo małych list.


Dwukrotne cofanie listy. Czy doda czas działania algorytmu z dużym marginesem w porównaniu z powyższym przyjętym rozwiązaniem?
Samyak Upadhyay

Dodaje 2n, więc tak, ale jeśli masz listę <50, nie byłbyś w stanie wykonać mikro-testu porównawczego różnicy na większości nowoczesnych maszyn
Patrick Favre

8

Możesz spojrzeć na add (int index, E element) :

Wstawia określony element w określonej pozycji na tej liście. Przesuwa element znajdujący się aktualnie na tej pozycji (jeśli istnieje) i wszelkie kolejne elementy w prawo (dodaje jeden do ich indeksów).

Po dodaniu możesz sprawdzić rozmiar ArrayList i usunąć te na końcu.


4

Możesz spojrzeć na Deque. daje bezpośredni dostęp do pierwszej i ostatniej pozycji na liście.


1
Dziwię się, że jesteś jedyną odpowiedzią mówiącą o Deque, jest to oczywiście najlepsze optymalne rozwiązanie.
Guillaume F.

3

To, co opisujesz, jest odpowiednią sytuacją do wykorzystania Queue.

Ponieważ chcesz addnowego elementu i removestarego. Możesz dodawać na końcu i usuwać od początku. To nie będzie miało większego znaczenia.

Kolejka ma metody add(e)i remove()która dodaje na końcu nowy element i odpowiednio usuwa z początku stary element.

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

Tak więc za każdym razem, gdy dodajesz element do elementu, queuemożesz utworzyć jego kopię zapasową za pomocą removewywołania metody.


AKTUALIZACJA : -

A jeśli chcesz poprawić rozmiarQueue , możesz spojrzeć na: -ApacheCommons#CircularFifoBuffer

Od documentation: -

CircularFifoBuffer jest pierwszym na pierwszym wejściu o stałym rozmiarze, który zastępuje najstarszy element, jeśli jest pełny.

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

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

Jak widać, po osiągnięciu maksymalnego rozmiaru, dodanie nowego elementu automatycznie usuwa pierwszy wstawiony element.


1

Myślę, że implementacja powinna być łatwa, ale biorąc pod uwagę wydajność, jako kontenera należy użyć LinkedList, ale nie ArrayList. Możesz odwołać się do następującego kodu:

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

możesz użyć tego kodu

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

Możesz używać metod listowych, usuwać i dodawać

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

0

Weź ten przykład: -

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

-1

Możesz użyć

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

}

Zmień E na swój typ danych

Jeśli usunięcie najstarszego elementu jest konieczne, możesz dodać:

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

przed zwrotem. W przeciwnym razie lista doda twój obiekt na początku i zachowa najstarszy element.

Spowoduje to usunięcie ostatniego elementu z listy.


-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

Miałem podobny problem, próbując dodać element na początku istniejącej tablicy, przesunąć istniejące elementy w prawo i odrzucić najstarszy (tablica [length-1]). Moje rozwiązanie może nie być bardzo wydajne, ale działa w moich celach.

 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

Powodzenia

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.