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?

ZeDonDino
źródło
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);
Baz
źródło
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.

Patrick Favre
źródło
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.

npinti
źródło
4

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

Evvo
źródło
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.

Rohit Jain
źródło
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);
        }
    }
}
feikiss
źródło
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);
    }
}
MaVRoSCy
źródło
0

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

list.add(lowestIndex, element);
list.remove(highestIndex, element);
Mnie_
źródło
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);
Ashish Mehta
źródło
-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.

uczący się
źródło
-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);
 }
}
Machhindra Neupane
źródło
-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

FabianUx
źródło