1
1
package com .bobocode .linked_list ;
2
2
3
-
4
- import com .bobocode .util .ExerciseNotCompletedException ;
3
+ import java .util .NoSuchElementException ;
4
+ import java .util .Objects ;
5
+ import java .util .stream .Stream ;
5
6
6
7
/**
7
8
* {@link LinkedList} is a list implementation that is based on singly linked generic nodes. A node is implemented as
10
11
* @param <T> generic type parameter
11
12
*/
12
13
public class LinkedList <T > implements List <T > {
14
+ private Node <T > head ;
15
+ private Node <T > tail ;
16
+ private int size ;
13
17
14
18
/**
15
19
* This method creates a list of provided elements
@@ -19,7 +23,9 @@ public class LinkedList<T> implements List<T> {
19
23
* @return a new list of elements the were passed as method parameters
20
24
*/
21
25
public static <T > List <T > of (T ... elements ) {
22
- throw new ExerciseNotCompletedException (); // todo: implement this method
26
+ LinkedList <T > linkedList = new LinkedList <>();
27
+ Stream .of (elements ).forEach (linkedList ::add );
28
+ return linkedList ;
23
29
}
24
30
25
31
/**
@@ -29,7 +35,7 @@ public static <T> List<T> of(T... elements) {
29
35
*/
30
36
@ Override
31
37
public void add (T element ) {
32
- throw new ExerciseNotCompletedException (); // todo: implement this method
38
+ add ( size , element );
33
39
}
34
40
35
41
/**
@@ -41,7 +47,51 @@ public void add(T element) {
41
47
*/
42
48
@ Override
43
49
public void add (int index , T element ) {
44
- throw new ExerciseNotCompletedException (); // todo: implement this method
50
+ Node <T > newNode = Node .valueOf (element );
51
+ if (index == 0 ) {
52
+ addAsHead (newNode );
53
+ } else if (index == size ) {
54
+ addAsTail (newNode );
55
+ } else {
56
+ add (index , newNode );
57
+ }
58
+ size ++;
59
+ }
60
+
61
+ private void addAsHead (Node <T > newNode ) {
62
+ newNode .next = head ;
63
+ head = newNode ;
64
+ if (head .next == null ) {
65
+ tail = head ;
66
+ }
67
+ }
68
+
69
+ private void addAsTail (Node <T > newNode ) {
70
+ tail .next = newNode ;
71
+ tail = newNode ;
72
+ }
73
+
74
+ private void add (int index , Node <T > newNode ) {
75
+ Node <T > node = findNodeByIndex (index - 1 );
76
+ newNode .next = node .next ;
77
+ node .next = newNode ;
78
+ }
79
+
80
+ private Node <T > findNodeByIndex (int index ) {
81
+ Objects .checkIndex (index , size );
82
+ if (index == size - 1 ) {
83
+ return tail ;
84
+ } else {
85
+ return nodeAt (index );
86
+ }
87
+ }
88
+
89
+ private Node <T > nodeAt (int index ) {
90
+ Node <T > currentNode = head ;
91
+ for (int i = 0 ; i < index ; i ++) {
92
+ currentNode = currentNode .next ;
93
+ }
94
+ return currentNode ;
45
95
}
46
96
47
97
/**
@@ -53,7 +103,8 @@ public void add(int index, T element) {
53
103
*/
54
104
@ Override
55
105
public void set (int index , T element ) {
56
- throw new ExerciseNotCompletedException (); // todo: implement this method
106
+ Node <T > node = findNodeByIndex (index );
107
+ node .value = element ;
57
108
}
58
109
59
110
/**
@@ -65,7 +116,8 @@ public void set(int index, T element) {
65
116
*/
66
117
@ Override
67
118
public T get (int index ) {
68
- throw new ExerciseNotCompletedException (); // todo: implement this method
119
+ Node <T > node = findNodeByIndex (index );
120
+ return node .value ;
69
121
}
70
122
71
123
/**
@@ -76,7 +128,8 @@ public T get(int index) {
76
128
*/
77
129
@ Override
78
130
public T getFirst () {
79
- throw new ExerciseNotCompletedException (); // todo: implement this method
131
+ checkElementsExist ();
132
+ return head .value ;
80
133
}
81
134
82
135
/**
@@ -87,20 +140,44 @@ public T getFirst() {
87
140
*/
88
141
@ Override
89
142
public T getLast () {
90
- throw new ExerciseNotCompletedException (); // todo: implement this method
143
+ checkElementsExist ();
144
+ return tail .value ;
145
+ }
146
+
147
+ private void checkElementsExist () {
148
+ if (head == null ) {
149
+ throw new NoSuchElementException ();
150
+ }
91
151
}
92
152
93
153
/**
94
154
* Removes an elements by its position index. In case provided index in out of the list bounds it
95
155
* throws {@link IndexOutOfBoundsException}
96
156
*
97
157
* @param index element index
158
+ * @return an element value
98
159
*/
99
160
@ Override
100
161
public void remove (int index ) {
101
- throw new ExerciseNotCompletedException (); // todo: implement this method
162
+ if (index == 0 ) {
163
+ Objects .checkIndex (index , size );
164
+ removeHead ();
165
+ } else {
166
+ Node <T > previousNode = findNodeByIndex (index - 1 );
167
+ previousNode .next = previousNode .next .next ;
168
+ if (index == size - 1 ) {
169
+ tail = previousNode ;
170
+ }
171
+ }
172
+ size --;
102
173
}
103
174
175
+ private void removeHead () {
176
+ head = head .next ;
177
+ if (head == null ) {
178
+ tail = null ;
179
+ }
180
+ }
104
181
105
182
/**
106
183
* Checks if a specific exists in he list
@@ -109,7 +186,14 @@ public void remove(int index) {
109
186
*/
110
187
@ Override
111
188
public boolean contains (T element ) {
112
- throw new ExerciseNotCompletedException (); // todo: implement this method
189
+ Node <T > currentNode = head ;
190
+ while (currentNode != null ) {
191
+ if (currentNode .value .equals (element )) {
192
+ return true ;
193
+ }
194
+ currentNode = currentNode .next ;
195
+ }
196
+ return false ;
113
197
}
114
198
115
199
/**
@@ -119,7 +203,7 @@ public boolean contains(T element) {
119
203
*/
120
204
@ Override
121
205
public boolean isEmpty () {
122
- throw new ExerciseNotCompletedException (); // todo: implement this method
206
+ return head == null ;
123
207
}
124
208
125
209
/**
@@ -129,14 +213,28 @@ public boolean isEmpty() {
129
213
*/
130
214
@ Override
131
215
public int size () {
132
- throw new ExerciseNotCompletedException (); // todo: implement this method
216
+ return size ;
133
217
}
134
218
135
219
/**
136
220
* Removes all list elements
137
221
*/
138
222
@ Override
139
223
public void clear () {
140
- throw new ExerciseNotCompletedException (); // todo: implement this method
224
+ head = tail = null ;
225
+ size = 0 ;
226
+ }
227
+
228
+ static class Node <T > {
229
+ private T value ;
230
+ private Node <T > next ;
231
+
232
+ private Node (T value ) {
233
+ this .value = value ;
234
+ }
235
+
236
+ public static <T > Node <T > valueOf (T value ) {
237
+ return new Node <>(value );
238
+ }
141
239
}
142
240
}
0 commit comments