View difference between Paste ID: vrk5qcB1 and RCkp2n4i
SHOW: | | - or go back to the newest paste.
1
import java.util.Iterator;
2
public class DoubleLinkedList<ELEMENT> implements ILinkedList<ELEMENT> {
3
    //region Node Class
4
     
5
    protected class Node<ELEMENT> {
6
        protected ELEMENT item;
7
        protected Node<ELEMENT> next;
8
        protected Node<ELEMENT> prev;
9
 
10
        protected Node() {
11
            this(null, null, null);
12
        }
13
        protected Node(ELEMENT item) {
14
            this(item, null, null);
15
        }
16
        protected Node(ELEMENT item, Node<ELEMENT> next) {
17
            this(item, next, null);
18
        }
19
        protected Node(ELEMENT item, Node<ELEMENT> next, Node<ELEMENT> prev) {
20
            this.item = item;
21
            this.next = next;
22
            this.prev = prev;
23
        }
24
 
25
        @Override
26
        public String toString() {
27
            return this.item.toString();
28
        }
29
    }
30
    //endregion
31
 
32
    //region Attributes
33
 
34
    protected Node<ELEMENT> head;
35
    protected int count;
36
    protected Node<ELEMENT> tail;
37
    //endregion
38
 
39
    //region Constructors
40
 
41
    public DoubleLinkedList() {
42
        this.head = null;
43
        this.count = 0;
44
        this.tail = null;
45
    }
46
    //endregion
47
 
48
    //region Linked List Methods
49
 
50
    // Returns the number of elements in this list.
51
    public int size() {
52
        return this.count;
53
    }
54
 
55
    public void addFirstRookieVersion(ELEMENT item) {
56
        if (this.size() <= 0) {
57
            this.head = this.tail = new Node<ELEMENT>(item, null, null);
58
            ++this.count;
59
        }
60
        else {
61
            Node<ELEMENT> temp = new Node<ELEMENT>(item, null, null);
62
            temp.next = this.head;
63
            this.head.prev = temp;
64
            this.head = temp;
65
            ++this.count;
66
        }
67
    }
68
    // Inserts the specified element at the beginning of this list.
69
    public void addFirst(ELEMENT item) {
70
        Node<ELEMENT> temp = new Node<ELEMENT>(item, this.head, null);
71
        if (this.size() <= 0) {
72
            this.tail = temp;
73
        }
74
        else {
75
            this.head.prev = temp;
76
        }
77
        this.head = temp;
78
        ++this.count;
79
    }
80
 
81
    public void addLastRookieVersion(ELEMENT item) {
82
        if (this.size() <= 0) {
83
            this.head = this.tail = new Node<ELEMENT>(item, null, null);
84
            ++this.count;
85
        }
86
        else {
87
            Node<ELEMENT> temp = new Node<ELEMENT>(item, null, null);
88
            temp.prev = this.tail;
89
            this.tail.next = temp;
90
            this.tail = temp;
91
            ++this.count;
92
        }
93
    }
94
    // Appends the specified element to the end of this list.
95
    public void addLast(ELEMENT item) {
96
        Node<ELEMENT> temp = new Node<ELEMENT>(item, null, this.tail);
97
        if (this.size() <= 0) {
98
            this.head = temp;
99
        }
100
        else {
101
            this.tail.next = temp;
102
        }
103
        this.tail = temp;
104
        ++this.count;
105
    }
106
 
107
    // Removes and returns the first element from this list.
108
    public ELEMENT removeFirst() {
109
        if (this.size() <= 0) {
110
            throw new RuntimeException("La lista está vacía...");
111
        }
112
        ELEMENT item = this.head.item;
113
        this.head = this.head.next;
114
        if (this.head == null) {
115
            this.tail = null;
116
        }
117
        else {
118
            this.head.prev = null;
119
        }
120
        --this.count;
121
        return item;
122
    }
123
 
124
    // Removes and returns the last element from this list.
125
    public ELEMENT removeLast() {
126
        if (this.size() <= 0) {
127
            throw new RuntimeException("La lista está vacía...");
128
        }
129
        ELEMENT item = this.tail.item;
130
        if (this.head.next == null) {
131
            this.head = this.tail = null;
132
        } else {
133
            this.tail = this.tail.prev;
134
            this.tail.next = null;
135
        }
136
        --this.count;
137
        return item;
138
    }
139
    //endregion
140
 
141
    //region Object Methods
142
 
143
    @Override
144
    public String toString() {
145
 
146
        if (this.size() <= 0) {
147
            return "";
148
        }
149
 
150
        // from https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/StringBuilder.html
151
        StringBuilder sb = new StringBuilder();
152
 
153
        sb.append("[" + this.head.item.toString());
154
        for (Node<ELEMENT> skip = this.head.next; skip != null; skip = skip.next) {
155
            sb.append(",\n " + skip.item.toString());
156
        }
157
        sb.append("]");
158
 
159
        return sb.toString();
160
    }
161
    //endregion
162
 
163
    //region Iterable Methods
164
    @Override
165
    public Iterator<ELEMENT> iterator() {
166
        return new DoubleLinkedListIterator(this.head);
167
    }
168
 
169
    public class DoubleLinkedListIterator implements Iterator<ELEMENT> {
170
        private Node<ELEMENT> current;
171
 
172
        public DoubleLinkedListIterator(Node<ELEMENT> current) {
173
            this.current = current;
174
        }
175
 
176
        @Override
177
        public boolean hasNext() {
178
            return this.current != null;
179
        }
180
 
181
        @Override
182
        public ELEMENT next() {
183
            if (!this.hasNext()) {
184
                throw new RuntimeException("La lista está vacía...");
185
            }
186
            ELEMENT item = this.current.item;
187
            this.current = this.current.next;
188
            return item;
189
        }
190
    }
191
 
192
    public Iterator<ELEMENT> iteratorBack() {
193
        return new DoubleLinkedListIteratorBack(this.tail);
194
    }
195
 
196
    public class DoubleLinkedListIteratorBack implements Iterator<ELEMENT> {
197
        private Node<ELEMENT> current;
198
 
199
        public DoubleLinkedListIteratorBack(Node<ELEMENT> current) {
200
            this.current = current;
201
        }
202
 
203
        @Override
204
        public boolean hasNext() {
205
            return this.current != null;
206
        }
207
 
208
        @Override
209
        public ELEMENT next() {
210
            if (!this.hasNext()) {
211
                throw new RuntimeException("La lista está vacía...");
212
            }
213
            ELEMENT item = this.current.item;
214
            this.current = this.current.prev;
215
            return item;
216
        }
217
 
218
    }
219
 
220
    //endregion
221
 
222
 
223
}
224