Create a LIFO stack system with discard when full in Java

3

I want to design a system, establishing a data warehouse method, stack style, but with the peculiarity that when the maximum is reached (3) the first element of the stack is eliminated, thus only keeping the last values.

General design:

While you can store a piece of data that puts them one after the other (1,2,3 ...)

1: A
2: B
3: C

If the stack is full and you want to add a new data, the first element is deleted and rotates with the others, so that the last data entered is the last one.

1: B
2: C
3: D

if another one is added (C, D, E) that is, only the last 3 inserted data are saved.

The type of data to be saved that is custom class TextDataStatus The TextDataStatus object

public class TextDataStatus {

    int action;
    String content;
    int start;
    int end;

    public TextDataStatus(int action, String content, int start, int end) {
        this.action = action;
        this.content = content;
        this.start = start;
        this.end = end;
    }

    public int getAction() {
        return action;
    }

    public void setAction(int action) {
        this.action = action;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }

    @Override
    public String toString() {
        return "TextDataStatus{" +
                "action=" + action +
                ", content='" + content + '\'' +
                ", start=" + start +
                ", end=" + end +
                '}';
    }
}

The extraction method must be LIFO (Last Input First Output) and it allows you to store duplicate data.

    
asked by Webserveis 03.07.2016 в 23:02
source

2 answers

5

Clarification:

You say you want a LIFO (last in first out - the last one that comes in is the first that comes out ), but the example you provide is a FIFO (first in first out - the first one that enters is the first one that comes out ), since you are eliminating the A that was the first to enter.

But do not worry, whatever your case (I understand that FIFO) someone has already dealt with the subject and Java has classes for it and, even if they are not exactly what you need, we are going to save most of the work.

FIFO: Queue

The Queue object is a particular implementation of LinkedList, it can make the stack of objects have its own order based on the equals and hashCode of the objects it contains, but by default, it is a FIFO stack such and as you can see:

EXAMPLE:

import java.util.LinkedList;
import java.util.Queue;

private final static String[] letras = { "A", "B", "C", "D", "E" };

Queue<String> fifo = new LinkedList<String>();

for (String s : letras) {
    fifo.add(s);
}

System.out.println(fifo);

while (!fifo.isEmpty()) {
    System.out.println("La que se añadio mas recientemente es " + fifo.remove());
    System.out.println(fifo);
}

DEPARTURE:

[A, B, C, D, E]
La que se añadio mas recientemente es A
[B, C, D, E]
La que se añadio mas recientemente es B
[C, D, E]
La que se añadio mas recientemente es C
[D, E]
La que se añadio mas recientemente es D
[E]
La que se añadio mas recientemente es E
[]

LimitedFIFOList<E>

From there, with a wrapper class that protects the add methods, you can control the maximum size and have a limit getter other than size() :

import java.util.LinkedList;

public class LimitedFIFOList<E> extends LinkedList<E> {
    private static final long serialVersionUID = 1L;
    private int limite;

    public LimitedFIFOList(int limite) {
        this.limite = limite;
    }

    @Override
    public boolean add(E o) {
        super.add(o);
        // si el tamaño fuera mayor eliminamos uno 
        while (size() > limite) { super.remove(); }
        return true;
    }

    public int getLimite() {
        return limite;
    }

    public void setLimite(int limite) {
        this.limite = limite;
    }    

}

That using the previous example:

private static void FIFO() {
    LimitedFIFOList<TextDataStatus> fifo = new LimitedFIFOList<TextDataStatus>(3);

    for (TextDataStatus d : datos) {
        fifo.add(d);
        System.out.println(fifo.toString());
    }
}

DEPARTURE:

[TextDataStatus{action=1, content='A', start=1, end=6}
]
[TextDataStatus{action=1, content='A', start=1, end=6}
, TextDataStatus{action=1, content='B', start=2, end=7}
]
[TextDataStatus{action=1, content='A', start=1, end=6}
, TextDataStatus{action=1, content='B', start=2, end=7}
, TextDataStatus{action=1, content='C', start=3, end=8}
]
[TextDataStatus{action=1, content='B', start=2, end=7}
, TextDataStatus{action=1, content='C', start=3, end=8}
, TextDataStatus{action=1, content='D', start=4, end=9}
]
[TextDataStatus{action=1, content='C', start=3, end=8}
, TextDataStatus{action=1, content='D', start=4, end=9}
, TextDataStatus{action=1, content='E', start=5, end=10}
]

LIFO Collection: Stack

Since we are and that the question is a bit confusing, we will also explain the LIFO classes that Java has and how to set a limit to have the parejíta complete. For this, we will use Stack .

  

The Stack class represents a last-in-first-out (LIFO) stack of objects . It extends class with five operations that allow a vector to be treated as a stack. The usual push and pop operations are provided, as well as a method to peek at the top item on the stack, a method to test for whether the stack is empty, and a method to search the stack for an item and discover how far it is from the top.

EXAMPLE:

import java.util.Stack;

private final static String[] letras = { "A", "B", "C", "D", "E" };

Stack<String> st = new Stack<String>();

for (String s : letras) {
    st.add(s);
}

System.out.println(st.toString());  //     [A, B, C, D, E]
// cambiando el tamaño a menos de los objetos que contiene
// elimina los ultimos objetos añadidos
st.setSize(3);
System.out.println(st.toString());  //     [A, B, C]
// pop quita el que se haya añadido el ultimo
st.pop();
System.out.println(st.toString());  //    [A, B]

DEPARTURE:

[A, B, C, D, E]
[A, B, C]
[A, B]

LimitedLIFOList<E>

If your case were this, the wrapper would be very similar, but with Stack

import java.util.Stack;

public class LimitedLIFOList<E> extends Stack<E> {
    private static final long serialVersionUID = 1L;
    private int limite;

    public LimitedLIFOList(int limite) {
        this.limite = limite;
    }

    @Override
    public boolean add(E o) {
        super.add(o);
        // si el tamaño fuera mayor eliminamos uno 
        while (size() > limite) { super.pop(); }
        return true;
    }

    public int getLimite() {
        return limite;
    }

    public void setLimite(int limite) {
        this.limite = limite;
    }
}

EXAMPLE:

private static void LIFO() {
    LimitedLIFOList<TextDataStatus> lifo = new LimitedLIFOList<TextDataStatus>(3);

    for (TextDataStatus d : datos) {
        lifo.add(d);
        System.out.println(lifo);

        if (lifo.size() == lifo.getLimite())
            System.out.println("quitamos > " + lifo.pop());
    }
}

DEPARTURE:

[TextDataStatus{action=1, content='A', start=1, end=6}
]
[TextDataStatus{action=1, content='A', start=1, end=6}
, TextDataStatus{action=1, content='B', start=2, end=7}
]
[TextDataStatus{action=1, content='A', start=1, end=6}
, TextDataStatus{action=1, content='B', start=2, end=7}
, TextDataStatus{action=1, content='C', start=3, end=8}
]
quitamos > TextDataStatus{action=1, content='C', start=3, end=8}

[TextDataStatus{action=1, content='A', start=1, end=6}
, TextDataStatus{action=1, content='B', start=2, end=7}
, TextDataStatus{action=1, content='D', start=4, end=9}
]
quitamos > TextDataStatus{action=1, content='D', start=4, end=9}

[TextDataStatus{action=1, content='A', start=1, end=6}
, TextDataStatus{action=1, content='B', start=2, end=7}
, TextDataStatus{action=1, content='E', start=5, end=10}
]
quitamos > TextDataStatus{action=1, content='E', start=5, end=10}

NOTES:

  • to achieve your goal you must implement a LimitedFIFOList
  • looking for information I have seen that the Apache guys (as no ... ^_^ ) already has an implementation called CircularFIFOQueue .
  • eye because it is possible to change the size, if you want to make it fixed, overwrite the setSize() so that it does not do anything.

    @Override
    public void setSize(int size) {
    }
    

I hope you have explained me well and clarified your doubts, even if you have any questions, contact me :) .

    
answered by 04.07.2016 / 10:25
source
1

Solved Thanks to the solution of @Jordi_Castilla I used the LimitedLIFOList method following the indications of him I have done the following:

public class LimitedLIFOList<E> extends Stack<E> {
    private int limite;

    public LimitedLIFOList(int limite) {
        this.limite = limite;
    }

    @Override
    public E push(E o) {
        super.push(o);
        if (size() > limite) { super.remove(0); }
        return o;
    }
}

Test:

LimitedLIFOList<TextDataStatus> fifo2 = new LimitedLIFOList<>(3);

fifo2.push(new TextDataStatus(1,"A",0,0));
fifo2.push(new TextDataStatus(1,"B",0,0));
fifo2.push(new TextDataStatus(2,"C",0,0));
fifo2.push(new TextDataStatus(1,"D",0,0));
fifo2.push(new TextDataStatus(1,"E",0,0));
fifo2.push(new TextDataStatus(3,"F",3,1));

Result:

I/System.out: TextDataStatus{action=1, content='D', start=0, end=0}
I/System.out: TextDataStatus{action=1, content='E', start=0, end=0}
I/System.out: TextDataStatus{action=3, content='F', start=3, end=1}
    
answered by 04.07.2016 в 18:12