Collections Stack-Kapazität begrenzen

Shadoka

Mitglied
Abend miteinander,

ich habe eine Undo-Funktion implementiert, die mit einem Stack arbeitet.
Jetzt würde ich allerdings gerne die Kapazität des Stacks begrenzen, damit ich den Speicher nicht so sehr belaste. Allerdings scheint es da keine Lösung seitens Java für zu geben, oder?

Falls nicht, eine mögliche Vorgehensweise (auch wenn sie nicht dem Prinzip eines Stacks entspricht) wäre doch, wenn ich die Methoden von Vector nutze, von der Stack erbt.
Wenn einmal die gewünschte Kapazität erreicht ist, macht man bei einem push() einen neuen Stack auf, der alle Elemente des alten Stacks bis oldStack.size()-1 bekommt und das neue Element eben obendrauf.

Für elegantere Lösungen bin auch auch offen :)
 
G

Gast2

Gast
Ich würde dafür nen ring buffer implementieren der automatisch die letzten Einträge überschreibt wenn der puffer voll ist. Sollte sehr einfach zu machen sein.
 

Shadoka

Mitglied
Sorry für Doppelpost, aber ich habe die Edit-Funktion nicht gefunden :/

Hab ich das Prinzip des RingBuffers hier richtig verstanden?

Java:
public void add(Command c) {
		int length = buffer.length;
		if (buffer[length - 1] != null) {
			for (int i = 1; i < length; i++) {
				buffer[i] = buffer[i - 1];
			}
			buffer[0] = c;
		} else {
			for (int i = 0; i < length; i++) {
				if (buffer[i] != null) {
					buffer[i] = c;
				}
			}
		}
	}

"buffer" ist ein einfaches Array.
 
G

Gast2

Gast
Ne, hast du scheinbar nicht verstanden ;)
Ein RingBuffer hat ne feste Größe, man kann also intern nen Array verwenden, das machst du ja bei dir auch schon. Dann hast du noch zwei Variablen. Eine enthält den Index der auf den aktuell "obersten" Eintrag zeigt, als zweites entweder die aktuelle Größe des Puffers, oder einen Zeiger auf den "untersten" Eintrag im Puffer.
Das Hinzufügen ist dann ganz einfach (current ist der Index des obersten Eintrags):
- Füge das Element an Position current+1 in das Array ein
- current um 1 erhöhen
- ggf. aktuelle Größe um 1 erhöhen
Stößt du ans Ende des Arrays musst du natürlich vorne weitermachen wenn neue Daten kommen, wie in nem Ring halt.
eximage-a224c2.png


EDIT:
So in etwa könntest du das machen:
Java:
public class RingStack<T> {
	
	private final Object[] buffer;
	
	private int leader;
	private int size;
	
	public RingStack (int size) {
		this.buffer = new Object[size];
		
		this.size = 0;
		this.leader = 0;
	}
	
	public void push (T t) {
		leader = wrapIndex(leader + 1);
		
		buffer[leader] = t;
		
		if (size < buffer.length) size++;
	}
	
	public T pull() {
		if (size == 0) {
			throw new ArrayIndexOutOfBoundsException("the stack is empty");
		}
		
		@SuppressWarnings("unchecked")
		T element = (T) buffer[leader]; // this cast is safe
		
		leader = wrapIndex(leader - 1);
		size--;
		
		return element;
	}
	
	public int getSize() {
		return size;
	}
	
	public int getCapacity() {
		return buffer.length;
	}
	
	private int wrapIndex(int index) {
		return (index + getCapacity()) % getCapacity();
	}
}
 
Zuletzt bearbeitet von einem Moderator:

Shadoka

Mitglied
Ah, ich glaube jetzt habe ich es verstanden. Ich habe jetzt noch 2 Variablen "put" und "get" angelegt.

Java:
	public void add(Command c) {
		buffer[put] = c;
		if (put == buffer.length-1) {
			put = 0;
			get++;
		} else {
			put++;
			if (put == get) {
				get++;
			}
		}
	}
	
	public Command get() {
		Command result = buffer[get];
		if (get == buffer.length-1) {
			get = 0;
		} else {
			get++;
		}
		return result;
	}

Gefällt mir auch besser, da man hier nicht mit null umgehen muss.

€: Danke, für das Beispiel, habe es erst nach meinem Post gesehen. Du hast du etwas wiederverwertbarer gehalten als ich, und im Gegensatz zu mir daran gedacht, was bei einem get() bei einem leeren Stack geschieht :D
Ich werde mir das morgen nochmal genauer anschauen, heute war ein langer Tag...danke nochmal!
€2:% anstelle von if-Abfragen ist natürlich auch schöner.
 
Zuletzt bearbeitet:

Mujahiddin

Top Contributor
Deine Methode ist mMn unnötig umständlich... Guck mal hier:

Java:
    public void add(Command c) {
        buffer[put] = c;
        put = ++put % buffer.length;
        if( put == get ) get++;
    }
    
    public Command get() {
        if( put == -1 ) /* puffer leer */
            throw new NoSuchElementException(); /* oder return null; wobei dann buffer[get] auch null liefert */
        Command result = buffer[get];
        get = ++get % buffer.length;
        return result;
    }

Da es sich um einen Ringpuffer handelt, brauchst du keine if-Abfragne, du brauchst einfach nur eine Moduloanweisung.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 IJVM, ich tue auf meinen Stack 100 und 120 rein, danach subtrahiere ich, macht die Maschine 100-120 oder 120-100? Allgemeine Java-Themen 8
berserkerdq2 Kann man in IJVM maximal 3 Werte im Stack haben? Allgemeine Java-Themen 3
M Stack umdrehen Allgemeine Java-Themen 2
H Stack mit bestimmter Aufgabe Allgemeine Java-Themen 62
L Stack overflow bei einer endrekursiven Funktion (Anwendung: Spezialform des Package Merge) Allgemeine Java-Themen 4
C Method Area, Stack, Heap Allgemeine Java-Themen 7
F Mehrere Threads - ein Stack Allgemeine Java-Themen 6
M Baum nach Stack plus Objektkonvertierung Allgemeine Java-Themen 5
V Performancefrage int-Vector/Stack Allgemeine Java-Themen 10
X Wie 'teuer' ist die Verwendung des Stack Trace ? Allgemeine Java-Themen 8
H Alternative zu Stack Allgemeine Java-Themen 3
G Java Logger ohne Stack Trace ausgaben. Allgemeine Java-Themen 2
V Unable to pop operand off an empty stack Allgemeine Java-Themen 2
P Funktionsweise von Stack- und Snakedatentypen? Code? Allgemeine Java-Themen 7
M Stack vergrößern? Allgemeine Java-Themen 7
R Entsprechung von Stack() im Collections Framework...? Allgemeine Java-Themen 4
D Größe der Zahlenkombinationen eines Arrays begrenzen Allgemeine Java-Themen 3
J Anzahl der Zeichen bei Eingabe begrenzen Allgemeine Java-Themen 5
Iron Monkey RandomAccessFile - Bestimmte Filesize begrenzen Allgemeine Java-Themen 4
G von-bis begrenzen Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben