ARRAY/List die sich immer wieder von vorne neu auffüllt ?

rIpP3r

Mitglied
Hey 😉,
also ich habe folgendes Problem:

Ich arbeite momentan an einem Projekt dass immer 10 bestimmte Daten (long werte) speichern soll.
d.h Sagen wir ich bekomme jede minute einen neuen Datensatz, hab ich erst 9 wird ein 10 dazu geschrieben. Hab ich schon 10 wird der erste Datensatz (automatisch) wieder überschrieben.
Gibt es dafür schon eine passende Implementierung? (irgend eine Array/List Art von der ich nix weis?)
Ich hoffe ihr versteht was ich meine 😉
Danke schonmal.
Lg
Gast
 
Bekannt ist mir sowas nicht, aber es ist ja leicht es selber zu machen:
du merkst dir die "aktuelle Position" und schreibst an die
Code:
(i+1)%10
-Stelle
Optional kannst du vllt. an Queue schrauben.
 
Was du suchst ist ein RingBuffer. Eine fertige Implementierung gibts in der StandardAPI glaube ich nicht, aber google liefert dir da schon nen paar Sourcecodes.
 
Von ner ArrayList ableiten, hm... fänd ich nicht so schön.
Das eingängiste wäre mit nem einfachen Array zu arbeiten. Nen Ringbuffer hat nunmal die Eigenschaft eine feste Größe zu haben die sich in der Regel nicht so schnell ändert.
Ich würde also nen Array mit 2 Zeigern versehen und fertig 🙂
 
du brauchst einen zeiger damit du weißt wo das nächste element gespeichert werden muss, und einen zweiten zeiger der dir anzeigt an welcher stelle als nächstes gelesen werden soll. (z.b. bei nem fifo buffer).
 
Man kommt eigentlich mit einem Zeiger aus.
Wie gesagt
Code:
curPos = (curPos+1)%10
wäre der Zeiger auf das zuletzt geschriebes Element und um i-tes (der Älteste Eintrag ist der 0.) Element zu lesen musst du
Code:
(curPos + 1 + i)%10
lesen.
(wobei man noch unterscheiden musste, ob alle 10 Einträge existieren, oder nicht)
 
Du brauchst ja zumindest schonmal die Informationen an welcher Stelle du gerade stehst und wieviele Elemente in deinem Buffer sind. Ich denke mit weniger Informationen kommst du nicht aus, oder hast du da ne idee?

Java:
public class RingBuffer<E> {

    private E[] items;
    private int size;
    private int last = 0;

    public RingBuffer() {
        this(10); // default size is 10
    }

    public RingBuffer(int capa) {
        items = (E[]) new Object[capa];
    }

    public void push(E item) {
        if (getSize() == items.length) {
            throw new IndexOutOfBoundsException("buffer overflow");
        }

        items[last] = item;
        last = (last + 1) % items.length;
        size++;
    }

    public E pop() {
        if (getSize() == 0) {
            throw new IndexOutOfBoundsException("buffer underflow");
        }

        int first = (last - size + items.length) % items.length;
        E item = items[first];
        size--;

        return item;
    }

    public int getSize() {
        return size;
    }

    public static void main(String[] args) {
        RingBuffer<Integer> buffer = new RingBuffer<Integer>(5);
       
        buffer.push(1);
        buffer.push(2);
        buffer.push(3);
        buffer.push(4);
        buffer.push(5);

        try {
            buffer.push(6);
        } catch (IndexOutOfBoundsException ioobe) {
            System.out.println("oops: " + ioobe);
        }
        
        try {
            while (true) {
                System.out.println("pop: " + buffer.pop());
            }
        } catch (IndexOutOfBoundsException ioobe) {
            System.out.println("oops: " + ioobe);
        }
    }
}
 
Öhm, warum ist das RingBuffer, wenn du ein buffer overflow schmeißt? oO
Ich dachte eher an sowas:
Java:
public class RingArray<E> {

	private E[] list;
	private int last;
	private int size;

	public RingArray(int max) {
		list = (E[]) new Object[max];
		last = -1;
		size = 0;
	}

	public void add(E item) {
		last = (last + 1) % list.length;
		list[last] = item;
		if (size < list.length) {
			size++;
		}
	}

	public E get(int index) {
		if (size == 0) {
			return null;
		}
		return list[(last + index + 1) % size];

	}

	public int getSize() {
		return size;
	}

	public static void main(String[] args) {
		RingArray<Integer> testArray = new RingArray<Integer>(5);
		testArray.add(1);
		testArray.add(2);
		testArray.add(3);

		System.out.println("0: " + testArray.get(0)); // muss 1 sein
		System.out.println("1: " + testArray.get(1)); // muss 2 sein

		testArray.add(4);
		System.out.println("0: " + testArray.get(0)); // muss immer noch 1 sein
		testArray.add(5);
		testArray.add(6);
		System.out.println("0: " + testArray.get(0)); // muss nun 2 sein
	}

}
 
Man könnte ja zB. auch eine ArrayBlockingQueue verwenden, wenn sie 10 Elemente hat, wird eben das erste entfernt bevor eine neues hinzugefügt wird.
 
Öhm, warum ist das RingBuffer, wenn du ein buffer overflow schmeißt? oO
Weils in meinen Augen wenig sinn macht wenn man sich die eigenen Daten überschreibt. Ein Buffer soll die Daten zwischenspeichern bis man Zeit hat diese zu verarbeiten. Es hat ja keinen Sinn wenn in der Wartezeit die Hälfte der Daten verloren geht 😛
 
Ok ich hatte jetzt nur an die Bereiche gedacht wo es notwendig ist dass keine Daten verloren gehen, aber ihr habt recht, es gibt durchaus auch anwendungsbereiche wo einen nur die letzten x datensätze interessieren.

Sonst sind ja die ganzen module-Rechnungen sinnlos.
Nicht wirklich, dadurch dass die Zeiger immer auf den Anfang und das Ende der Daten anzeigen spart man sich ständiges umkopieren der Daten an den Anfang.

EDIT:
RingBuffer 2.0
Java:
public class RingBuffer<E> {

    private E[] items;
    private int size = 0;
    private int last = 0;

    private boolean overrideData = true;
    
    public RingBuffer() {
        this(10); // default size is 10
    }

    public RingBuffer(int capa) {
        items = (E[]) new Object[capa];
    }

    public void push(E item) {
        if (!overrideData && getSize() == items.length) {
            throw new IndexOutOfBoundsException("buffer overflow");
        }

        items[last] = item;
        last = (last + 1) % items.length;
        size = Math.min((size+1), items.length);
    }

    public E pop() {
        if (getSize() == 0) {
            throw new IndexOutOfBoundsException("buffer underflow");
        }

        int first = (last - size + items.length) % items.length;
        E item = items[first];
        size--;

        return item;
    }

    public int getSize() {
        return size;
    }

    public boolean isOverrideData() {
        return overrideData;
    }

    public void setOverrideData(boolean overrideData) {
        this.overrideData = overrideData;
    }
}
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben