Skip to content

Instantly share code, notes, and snippets.

@yuri-potatoq
Created March 21, 2026 16:53
Show Gist options
  • Select an option

  • Save yuri-potatoq/715d58455a8c71db22eaf853f8cdcfe2 to your computer and use it in GitHub Desktop.

Select an option

Save yuri-potatoq/715d58455a8c71db22eaf853f8cdcfe2 to your computer and use it in GitHub Desktop.
Java text editor undo with Stack ADT
import java.util.ArrayList;
import java.util.List;
enum TokenKind {
WORD, SPACE
}
record TextEditorToken(String content, TokenKind kind) {}
class Stack<T> {
private List<T> items = new ArrayList<>();
private int size = 0;
public void push(T item) {
this.items.add(item);
this.size++;
}
public T pop() {
if (this.size < 1) return null;
T it = this.items.get(size - 1);
this.items = new ArrayList<>(this.items.subList(0, size - 1));
this.size--;
return it;
}
public T get() {
if (this.size < 1) return null;
return this.items.get(this.size - 1);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
int counter = this.size - 1;
while (counter >= 0) {
sb.append(this.items.get(counter))
.append(" -> [")
.append(counter)
.append("]\n");
counter--;
}
return sb.toString();
}
}
class TextEditor {
private final Stack<TextEditorToken> stack;
public TextEditor(Stack<TextEditorToken> stack) {
this.stack = stack;
}
public void write(String line) {
for (TextEditorToken token : new Parser(line).parseLine()) {
this.stack.push(token);
}
}
public void undo() {
this.stack.pop();
}
private class Parser {
private int cursor = 0;
private String line;
private final int lineSize;
Parser(String line) {
this.line = line;
this.lineSize = line.length();
}
List<TextEditorToken> parseLine() {
List<TextEditorToken> items = new ArrayList<>();
while (this.cursor < this.lineSize) {
char ch = this.line.charAt(this.cursor);
if (ch == ' ') {
String space = ch + this.collectWord(true);
items.add(new TextEditorToken(space, TokenKind.SPACE));
} else {
String word = ch + this.collectWord(false);
items.add(new TextEditorToken(word, TokenKind.WORD));
}
cursor++;
}
return items;
}
private String peekNext() {
if (this.cursor + 1 > this.lineSize - 1) return null;
return String.valueOf(line.charAt(this.cursor + 1));
}
private String collectWord(boolean isSpace) {
StringBuilder word = new StringBuilder();
while (true) {
String tk = this.peekNext();
if (tk == null) return word.toString();
if (isSpace) {
if (tk.equals(" ")) {
word.append(tk);
this.cursor++;
} else {
return word.toString();
}
} else {
if (!tk.equals(" ")) {
word.append(tk);
this.cursor++;
} else {
return word.toString();
}
}
}
}
}
}
public class Main {
public static void main(String[] args) {
try {
var stack = new Stack<TextEditorToken>();
TextEditor te = new TextEditor(stack);
te.write("Olá mundo eu gosto de batata");
te.undo();
te.undo();
te.undo();
te.undo();
te.undo();
te.undo();
te.undo();
te.write("isso é um test");
System.out.println(stack.toString());
} catch (Exception err) {
System.out.println("Erro desconhecido: " + err.getMessage());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment