Java ArrayList başında eleman ekleme


183

Ne ArrayListolursa olsun bir sıraya öğeleri eklemeniz gerekir , ancak bir öğe eklemek için işlev çağırdığınızda, dizinin başında öğe eklemek istiyorum (böylece en düşük dizin vardır) ve dizi 10 öğeleri ekleme varsa en eski öğeyi (en yüksek dizine sahip olan) silmeyle ilgili yeni bir sonuç.

Kimsenin önerisi var mı?


Eğer gibi mi demek istiyorsun removeve add?
Peter Lawrey

Ne için arraylist stack queue whateverbir dizi başlangıcına eklemek için kullandığınız en iyi kaçınılmalıdır ve farklı bir koleksiyon kullanıyor gibi geliyor.
Peter Lawrey

İlk olarak, kendiniz bir şeyler yapmalısınız. Şimdiye kadar ne yaptın?
Yegoshin Maxim

Yanıtlar:


301

Listyöntemi vardır add(int, E), böylece kullanabilirsiniz:

list.add(0, yourObject);

Daha sonra, son öğeyi aşağıdakilerle silebilirsiniz:

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

Ancak, gereksinimlerinizi yeniden düşünmek veya farklı bir veri yapısı kullanmak isteyebilirsiniz. Queue

DÜZENLE

Belki de Apache'ye bir göz atın CircularFifoQueue:

CircularFifoQueue doluysa, en eski öğesini değiştiren sabit boyutlu ilk giren ilk çıkar kuyruğudur.

Sadece maksimum boyutla başlat:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
Özellikle guava'nın toplama sınıfları olduğundan, on metrelik bir direğe sahip hiçbir apache kütüphanesine dokunmam. Guava EvictingQueue burada iyi bir seçim olabilir.
DPM

26

Belirli Veri Yapılarını Kullanma

İlk dizine eleman eklemek için optimize edilmiş çeşitli veri yapıları vardır. Bununla birlikte, koleksiyonunuzu bunlardan birine dönüştürürseniz, sohbetin muhtemelen bir zaman ve alan karmaşıklığına ihtiyacı olacaktır.O(n)

deque

JDK içeren Dequeteklifler yöntemleri gibi yapı addFirst(e)veofferFirst(e)

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

analiz

Yerleştirmenin uzay ve zaman karmaşıklığı LinkedListsabittir ( O(1)). Bkz Big-O Pardus .

Listeyi Ters Çevirme

Çok kolay ama verimsiz bir yöntem tersini kullanmaktır:

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

Java 8 akışları kullanıyorsanız, bu cevap ilginizi çekebilir.

analiz

  • Zaman Karmaşıklığı: O(n)
  • Alan Karmaşıklığı: O(1)

JDK uygulamasına bakıldığında, bu O(n)zaman karmaşıklığına sahiptir, bu nedenle yalnızca çok küçük listeler için uygundur.


Bir listeyi iki kez ters çevirme. Yukarıda kabul edilen çözümle karşılaştırıldığında algoritmanın çalışma süresini büyük bir farkla ekleyecek mi?
Samyak Upadhyay

2n ekliyor, bu yüzden evet, ancak <50 listeniz varsa, çoğu modern makinedeki farkı
ölçemezsiniz

8

Eklemeye bir göz atabilirsiniz (int index, E element) :

Belirtilen öğeyi bu listede belirtilen konuma ekler. Şu anda o konumda bulunan (varsa) öğeyi ve sonraki öğeleri sağa kaydırır (dizinlerine bir öğe ekler).

Ekledikten sonra ArrayList'in boyutunu kontrol edebilir ve sonunda olanları kaldırabilirsiniz.


4

Deque'ye bakmak isteyebilirsiniz. listedeki ilk ve son öğelere doğrudan erişim sağlar.


1
Deque hakkında konuşan tek cevap siz olduğuna şaşırıyorum, bu en iyi çözüm.
Guillaume F.

3

Açıkladığınız şey, kullanmak için uygun bir durumdur Queue.

Çünkü addyeni eleman ve removeeskisini istiyorum . Sonuna ekleyebilir ve baştan kaldırabilirsiniz. Bu çok fazla fark yaratmayacak.

Kuyruğun yöntemleri vardır add(e)ve remove()bunlar sonunda yeni öğeyi ekler ve sırasıyla eski öğenin başından kaldırılır.

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

Böylece, her öğe eklediğinizde, queueonu bir removeyöntem çağrısı ile yedekleyebilirsiniz .


GÜNCELLEME : -

Ve boyutunu düzeltmekQueue istiyorsanız , o zaman bir göz atabilirsiniz: -ApacheCommons#CircularFifoBuffer

Gönderen documentation: -

CircularFifoBuffer, doluysa en eski öğesini değiştiren sabit boyutlu ilk giren ilk çıkar arabelleğidir.

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

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

Gördüğünüz gibi, maksimum boyuta ulaşıldığında, yeni öğe eklemek, eklenen ilk öğeyi otomatik olarak kaldırır.


1

Makinenin kolay olması gerektiğini düşünüyorum, ancak verimliliği göz önünde bulundurarak, kapsayıcı olarak LinkedList kullanmalısınız, ancak ArrayList kullanmamalısınız. Aşağıdaki koda başvurabilirsiniz:

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

bu kodu kullanabilirsiniz

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

Liste yöntemlerini kullanabilir, kaldırabilir ve ekleyebilirsiniz

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

0

Bu örneği ele alalım: -

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

-1

Kullanabilirsiniz

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

}

Veri türünüzle E'yi değiştirin

En eski öğeyi silmek gerekiyorsa şunları ekleyebilirsiniz:

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

iade beyanından önce. Aksi takdirde liste nesnenizi başlangıçta ekler ve en eski öğeyi korur.

Bu listedeki son elemanı silecektir.


-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

Ben benzer bir sorun vardı, varolan bir dizinin başında bir öğe eklemek çalışarak, var olan öğeleri sağa kaydırın ve en eski olanı (dizi [uzunluk-1]) atın. Çözümüm çok başarılı olmayabilir ama benim amacım için işe yarıyor.

 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

İyi şanslar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.