何でもArrayList
キューに要素を追加する必要があります、しかし要素を追加するために関数を呼び出すとき、私はそれが配列の先頭に要素を追加するようにしたいです(だからそれは最も低いインデックスを持っています)新しい要素を追加すると、最も古い要素(最も高いインデックスを持つ要素)が削除されます。
誰かが何か提案がありますか?
List
にはメソッド add(int, E)
があるので、次のようにします。
list.add(0, yourObject);
その後、最後の要素を削除することができます。
if(list.size() > 10)
list.remove(list.size() - 1);
ただし、 Queue
のように、要件を考え直すか、別のデータ構造を使用することをお勧めします。
EDIT
たぶん、Apacheの CircularFifoQueue
を見てください。
CircularFifoQueue
は、最も古い要素がいっぱいになった場合に置き換えられる固定サイズの先入れ先出しキューです。
最大サイズで初期化するだけです。
CircularFifoQueue queue = new CircularFifoQueue(10);
最初のインデックスに要素を追加するために最適化されているさまざまなデータ構造があります。ただし、コレクションをこれらのいずれかに変換する場合、会話にはおそらくO(n)
という時間と空間の複雑さが必要になるでしょう。
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)
の時間の複雑さを伴うので、非常に小さいリストにのみ適しています。
add(int index、E element) を見てください。
指定された要素をこのリストの指定された位置に挿入します。現在その位置にある要素(ある場合)とそれに続く要素を右に移動します(インデックスに1を加えます)。
追加したら、ArrayListのサイズを確認し、最後に削除します。
あなたはDequeを見たいと思うかもしれません。リストの最初と最後の両方の項目に直接アクセスできます。
説明しているのは、 Queue
を使用する適切な状況です。
add
の新しい要素と、remove
の古い要素が必要なので。最後に追加し、最初から削除できます。それは大きな違いにはなりません。
キューにはメソッドadd(e)
とremove()
があり、それぞれ新しい要素を最後に追加し、古い要素を最初から削除します。
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(5);
queue.add(6);
queue.remove(); // Remove 5
そのため、queue
に要素を追加するたびに、remove
メソッド呼び出しでバックアップできます。
UPDATE:-
そして、で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`
ご覧のとおり、最大サイズに達すると、新しい要素を追加すると、挿入された最初の要素が自動的に削除されます。
実装は簡単であるべきだと思いますが、効率性を考えると、コンテナとしてLinkedListを使用し、ArrayListは使用しないでください。次のコードを参照することができます。
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);
}
}
}
Java LinkedListは、リストの先頭に要素を追加するaddFirst(E e)メソッドとPush(E e)メソッドの両方を提供します。
https://docs.Oracle.com/javase/7/docs/api/Java/util/LinkedList.html#addFirst(E)
あなたはこのコードを使うことができます
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);
}
}
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);
}
}
既存の配列の先頭に要素を追加し、既存の要素を右にシフトし、最も古いもの(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
がんばろう
リストメソッドを使用したり、削除したり追加したりできます。
list.add(lowestIndex, element);
list.remove(highestIndex, element);
あなたが使用することができます
public List<E> addToListStart(List<E> list, E obj){
list.add(0,obj);
return (List<E>)list;
}
データ型に合わせてEを変更してください。
最も古い要素を削除する必要がある場合は、追加できます。
list.remove(list.size()-1);
returnステートメントの前そうでなければ、listは最初にあなたのオブジェクトを追加し、最も古い要素も保持します。
これはリストの最後の要素を削除します。