CCCPaste

SimpleLinkedList

import java.util.Iterator;

public class SimpleLinkedList implements ILinkedList {

    //region Node Class
    private static class Node {

        public ELEMENT item;
        public Node next;

        public Node() {
            this(null, null);
        }

        public Node(ELEMENT item) {
            this(item, null);
        }

        public Node(ELEMENT item, Node next) {
            this.item = item;
            this.next = next;
        }

        @Override
        public String toString() {
            return this.item.toString();
        }
    }
    //endregion

    //region Attributes
    protected Node head;
    protected int count;
    protected Node tail;
    //endregion

    //region Constructors
    public SimpleLinkedList() {
        this.head = null;
        this.count = 0;
        this.tail = null;
    }
    //endregion

    //region Linked List Methods
    // Returns the number of elements in this list.
    @Override
    public int size() {
        return this.count;
    }

    public void addFirstRookieVersion(ELEMENT item) {
        if (this.count == 0) {
            this.head = this.tail = new Node(item, null);
            ++this.count;
        } else {
            Node temp = new Node<>(item, null);
            temp.next = this.head;
            this.head = temp;
            ++this.count;
        }
    }

    // Inserts the specified element at the beginning of this list.
    @Override
    public void addFirst(ELEMENT item) {
        Node temp = new Node<>(item, this.head);
        if (this.count == 0) {
            this.tail = temp;
        }
        this.head = temp;
        ++this.count;
    }

    public void addLastRookieVersion(ELEMENT item) {
        if (this.count == 0) {
            this.head = this.tail = new Node(item, null);
            ++this.count;
        } else {
            Node temp = new Node<>(item, null);
            this.tail.next = temp;
            this.tail = temp;
            ++this.count;
        }
    }

    // Appends the specified element to the end of this list.
    @Override
    public void addLast(ELEMENT item) {
        Node temp = new Node<>(item, null);
        if (this.count == 0) {
            this.head = temp;
        } else {
            this.tail.next = temp;
        }
        this.tail = temp;
        ++this.count;
    }

    // Removes and returns the first element from this list.
    @Override
    public ELEMENT removeFirst() {
        if (this.count == 0) {
            throw new RuntimeException("La lista está vacía...");
        }
        ELEMENT item = this.head.item;
        this.head = this.head.next;
        if (this.head == null) {
            this.tail = null;
        }
        --this.count;
        return item;
    }

    // Removes and returns the last element from this list.
    @Override
    public ELEMENT removeLast() {
        if (this.count == 0) {
            throw new RuntimeException("La lista está vacía...");
        }
        ELEMENT item = this.tail.item;
        if (this.head.next == null) {
            this.head = this.tail = null;
        } else {
            Node skip = this.head;
            while (skip.next.next != null) {
                skip = skip.next;
            }
            this.tail = skip;
            this.tail.next = null;
        }
        --this.count;
        return item;
    }
    //endregion

    //region Object Methods
    @Override
    public String toString() {

        if (this.size() <= 0) {
            return "";
        }

        // from https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/StringBuilder.html
        StringBuilder sb = new StringBuilder();

        sb.append("[").append(this.head.item.toString());
        for (Node skip = this.head.next; skip != null; skip = skip.next) {
            sb.append(", ").append(skip.item.toString());
        }
        sb.append("]");

        return sb.toString();
    }
    //endregion

    // public ELEMENT removeItem(ELEMENT item) {
    //     if (this.count == 0) {
    //         throw new RuntimeException("La lista está vacía...");
    //     }
        
    //     if (this.head.item.compareTo(item) == 0) {
    //         return this.removeFirst();
    //     }
    //     if (this.tail.item.compareTo(item) == 0) {
    //         return this.removeLast();
    //     }
        
    //     for (Node skip = this.head; skip != null; skip = skip.next) {
    //         if (skip.next.item.compareTo(item) == 0) {
    //             ELEMENT temp = skip.next.item;
    //             skip.next = skip.next.next;
    //             return temp;
    //         }
    //     }

    //     return null;
    // }

    //region Iterable Methods
    @Override
    public Iterator iterator() {
        return new SimpleLinkedListIterator(this.head);
    }

    private class SimpleLinkedListIterator implements Iterator {

        private Node current;

        public SimpleLinkedListIterator(Node current) {
            this.current = current;
        }

        @Override
        public boolean hasNext() {
            return this.current != null;
        }

        @Override
        public ELEMENT next() {
            if (!this.hasNext()) {
                throw new RuntimeException("La lista está vacía...");
            }
            ELEMENT item = this.current.item;
            this.current = this.current.next;
            return item;
        }

    }

    //endregion
}