Java ArrayList最初に要素を追加する方法


183

ArrayListなんでもキューに要素を追加する必要がありますが、要素を追加する関数を呼び出すと、配列の先頭に要素を追加して(インデックスが最小になるように)、配列に10要素がある場合は追加します新しい結果として、最も古い要素(インデックスが最も高い要素)が削除されます。

誰か提案はありますか?


あなたは次のように意味するかremoveadd
Peter Lawrey、2012年

arraylist stack queue whatever配列の先頭に追加するために何を使用しているのかを避けるのが最善であり、別のコレクションを使用する必要があるようです。
Peter Lawrey、

まず、自分で何かを作るべきです。これまでに何をしましたか?
Yegoshin Maxim

回答:


301

Listメソッドを持っているadd(int, E)ので、あなたは使うことができます:

list.add(0, yourObject);

その後、次のコマンドで最後の要素を削除できます。

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

ただし、要件を再検討したり、別のデータ構造を使用したりすることもできます。 Queue

編集

たぶんApacheのを見てくださいCircularFifoQueue

CircularFifoQueue フルの場合、最も古い要素を置き換える固定サイズの先入れ先出しキューです。

最大サイズで初期化するだけです:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
特にグアバのコレクションクラスが存在するので、10フィートのポールが付いたApacheライブラリには触れません。GuavaのEvictingQueueは、ここでの良い選択かもしれません。
DPM 2017

26

特定のデータ構造の使用

最初のインデックスに要素を追加するために最適化されたさまざまなデータ構造があります。ただし、コレクションをこれらのいずれかに変換する場合、会話にはおそらく時間とスペースの複雑さが必要になることに注意してください。O(n)

Deque

JDKには、およびのDequeようなメソッドを提供する構造が含まれていますaddFirst(e)offerFirst(e)

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

分析

挿入の空間と時間の複雑さはLinkedList定数(O(1))を使用します。Big-Oチートシートをご覧ください。

リストを逆にする

非常に簡単だが非効率的な方法は、reverseを使用することです。

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

Java 8ストリームを使用している場合、この回答は興味深いかもしれません。

分析

  • 時間の複雑さ: O(n)
  • スペースの複雑さ: O(1)

JDK実装を見ると、これはO(n)時間的に複雑であるため、非常に小さなリストにのみ適しています。


リストを2回反転します。上記の受け入れられたソリューションと比較して、アルゴリズムの実行時間を大幅に追加しますか?
Samyak Upadhyay 2017

2nを追加するので、はい。ただし、50未満のリストがある場合、最新のほとんどのマシンで違いをマイクロベンチマークできない
Patrick Favre

8

あなたはを見てとることができ、追加(int型のインデックス、Eの要素)

リストの指定された位置に指定された要素を挿入します。現在その位置にある要素(存在する場合)と後続の要素を右に移動します(インデックスに1を加えます)。

追加したら、ArrayListのサイズを確認し、最後のサイズを削除できます。


4

Dequeを確認することをお勧めします。リストの最初と最後の項目の両方に直接アクセスできます。


1
Dequeについて話している唯一の答えがあなたであることに驚いています。これが明らかに最良の最適なソリューションです。
ギヨームF.16年

3

あなたが説明しているのは、使用するのに適切な状況Queueです。

add新しい要素とremove古いものにしたいので。最後に追加し、最初から削除できます。それは大きな違いはありません。

Queueにはメソッドがadd(e)ありremove()、新しい要素を最後に追加し、古い要素を最初から削除します。

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

したがって、要素をに追加するたびにqueueremoveメソッド呼び出しを使用して要素をバックアップできます。


更新:-

のサイズを修正しQueueたい場合、次の点を確認してください。-ApacheCommons#CircularFifoBuffer

からdocumentation:-

CircularFifoBufferは、満杯の場合に最も古い要素を置き換える固定サイズの先入れ先出しバッファです。

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

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

ご覧のとおり、最大サイズに達すると、新しい要素を追加すると、挿入された最初の要素が自動的に削除されます。


1

実装は簡単だと思いますが、効率を考えると、コンテナとしてArrayListではなくLinkedListを使用する必要があります。次のコードを参照できます。

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

このコードを使用できます

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

リストメソッドを使用して、削除および追加できます

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

0

この例を見てみましょう:-

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

-1

使用できます

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

}

Eをデータ型で変更する

最も古い要素を削除する必要がある場合は、以下を追加できます。

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

returnステートメントの前。そうでない場合、リストは最初にオブジェクトを追加し、最も古い要素も保持します。

リストの最後の要素を削除します。


-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

同様の問題があり、既存の配列の先頭に要素を追加し、既存の要素を右にシフトして、最も古い要素(array [length-1])を破棄しようとしました。私の解決策はあまり性能が良くないかもしれませんが、それは私の目的のために機能します。

 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

幸運を

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.