dividir la oración en palabras y puntuaciones

Necesito analizar la claseSentence en palabra y puntuación (el espacio en blanco se considera como un signo de puntuación), luego agréguelo todo en generalArrayList<Sentence>.

Una oración de ejemplo:

Un hombre, un plan, un canal - ¡Panamá!
A => palabra
whitespase => puntuación
man => palabra
, + espacio => puntuación
a => palabra
[...]

Intenté leer toda esta oración un carácter a la vez y recopilar la misma y crear una nueva palabra o una nueva.Punctuation de esta colección.

Aquí está mi código:

public class Sentence {

    private String sentence;
    private LinkedList<SentenceElement> elements;

    /**
     * Constructs a sentence.
     * @param aText a string containing all characters of the sentence
     */
    public Sentence(String aText) {
        sentence = aText.trim();
        splitSentence();
    }

    public String getSentence() {
        return sentence;
    }

    public LinkedList<SentenceElement> getElements() {
        return elements;
    }

    /**
     * Split sentance into words and punctuations
     */
    private void splitSentence() {
        if (sentence == "" || sentence == null || sentence == "\n") {
            return;
        }

        StringBuilder builder = new StringBuilder();

        int j = 0;
        boolean mark = false;
        while (j < sentence.length()) {
            //char current = sentence.charAt(j);

            while (Character.isLetter(sentence.charAt(j))) {
                if (mark) {
                    elements.add(new Punctuation(builder.toString()));
                    builder.setLength(0);
                    mark = false;
                }
                builder.append(sentence.charAt(j));
                j++;
            } 
            mark = true;

            while (!Character.isLetter(sentence.charAt(j))) {
                if (mark) {
                    elements.add(new Word(builder.toString()));
                    builder.setLength(0);
                    mark = false;
                }
                builder.append(sentence.charAt(j));
                j++;
            }
            mark = true;
        }
    }

Pero la lógica de splitSentence () no funciona correctamente. Y no puedo encontrar la solución correcta para ello.

Quiero implementar esto mientras leemos el primer carácter => agregar al constructor => hasta que el siguiente elemento sea del mismo tipo (letra o puntuación) seguir agregando al constructor => cuando el siguiente elemento sea diferente al contenido del constructor => crear una nueva palabra o puntuacion y establecer constructor para iniciar.

Haz la misma lógica otra vez.

¿Cómo implementar esta lógica de comprobación de la manera correcta?

Respuestas a la pregunta(1)

Su respuesta a la pregunta