Skip to content

Commit be9ea81

Browse files
williamfisetclaude
andauthored
Cleanup DoublyLinkedList: fix API, simplify code, expand tests (williamfiset#1260)
* Cleanup DoublyLinkedList and expand test coverage - Add proper import for java.util.Iterator instead of inline qualified names - Change addAt to throw IndexOutOfBoundsException instead of checked Exception - Remove pointless local variable assignments in clear() and remove(Node) - Move trav declaration to point of use in remove(Object) - Replace inline java.util imports with proper imports in tests - Expand test suite from 18 to 30 tests covering contains, indexOf, null handling, invalid indices, iterator, and forEach Co-Authored-By: Claude Opus 4.6 <[email protected]> * Disallow null elements in DoublyLinkedList - Reject null in addFirst/addLast with IllegalArgumentException - Simplify remove(Object) and indexOf(Object) by removing null branches - Replace null-related tests with testNullRejection - Remove null entries from randomized test data generators Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
1 parent d5dc0b8 commit be9ea81

File tree

2 files changed

+149
-61
lines changed

2 files changed

+149
-61
lines changed

src/main/java/com/williamfiset/algorithms/datastructures/linkedlist/DoublyLinkedList.java

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
package com.williamfiset.algorithms.datastructures.linkedlist;
77

8+
import java.util.Iterator;
9+
810
public class DoublyLinkedList<T> implements Iterable<T> {
911
private int size = 0;
1012
private Node<T> head = null;
@@ -36,7 +38,7 @@ public void clear() {
3638
trav.data = null;
3739
trav = next;
3840
}
39-
head = tail = trav = null;
41+
head = tail = null;
4042
size = 0;
4143
}
4244

@@ -57,6 +59,7 @@ public void add(T elem) {
5759

5860
// Add a node to the tail of the linked list, O(1)
5961
public void addLast(T elem) {
62+
if (elem == null) throw new IllegalArgumentException("Null elements are not allowed");
6063
if (isEmpty()) {
6164
head = tail = new Node<T>(elem, null, null);
6265
} else {
@@ -68,6 +71,7 @@ public void addLast(T elem) {
6871

6972
// Add an element to the beginning of this linked list, O(1)
7073
public void addFirst(T elem) {
74+
if (elem == null) throw new IllegalArgumentException("Null elements are not allowed");
7175
if (isEmpty()) {
7276
head = tail = new Node<T>(elem, null, null);
7377
} else {
@@ -78,9 +82,9 @@ public void addFirst(T elem) {
7882
}
7983

8084
// Add an element at a specified index
81-
public void addAt(int index, T data) throws Exception {
85+
public void addAt(int index, T data) {
8286
if (index < 0 || index > size) {
83-
throw new Exception("Illegal Index");
87+
throw new IndexOutOfBoundsException("Illegal index: " + index);
8488
}
8589
if (index == 0) {
8690
addFirst(data);
@@ -173,7 +177,7 @@ private T remove(Node<T> node) {
173177

174178
// Memory cleanup
175179
node.data = null;
176-
node = node.prev = node.next = null;
180+
node.prev = node.next = null;
177181

178182
--size;
179183

@@ -207,23 +211,10 @@ public T removeAt(int index) {
207211

208212
// Remove a particular value in the linked list, O(n)
209213
public boolean remove(Object obj) {
210-
Node<T> trav = head;
211-
212-
// Support searching for null
213-
if (obj == null) {
214-
for (trav = head; trav != null; trav = trav.next) {
215-
if (trav.data == null) {
216-
remove(trav);
217-
return true;
218-
}
219-
}
220-
// Search for non null object
221-
} else {
222-
for (trav = head; trav != null; trav = trav.next) {
223-
if (obj.equals(trav.data)) {
224-
remove(trav);
225-
return true;
226-
}
214+
for (Node<T> trav = head; trav != null; trav = trav.next) {
215+
if (obj.equals(trav.data)) {
216+
remove(trav);
217+
return true;
227218
}
228219
}
229220
return false;
@@ -232,21 +223,9 @@ public boolean remove(Object obj) {
232223
// Find the index of a particular value in the linked list, O(n)
233224
public int indexOf(Object obj) {
234225
int index = 0;
235-
Node<T> trav = head;
236-
237-
// Support searching for null
238-
if (obj == null) {
239-
for (; trav != null; trav = trav.next, index++) {
240-
if (trav.data == null) {
241-
return index;
242-
}
243-
}
244-
// Search for non null object
245-
} else {
246-
for (; trav != null; trav = trav.next, index++) {
247-
if (obj.equals(trav.data)) {
248-
return index;
249-
}
226+
for (Node<T> trav = head; trav != null; trav = trav.next, index++) {
227+
if (obj.equals(trav.data)) {
228+
return index;
250229
}
251230
}
252231
return -1;
@@ -258,8 +237,8 @@ public boolean contains(Object obj) {
258237
}
259238

260239
@Override
261-
public java.util.Iterator<T> iterator() {
262-
return new java.util.Iterator<T>() {
240+
public Iterator<T> iterator() {
241+
return new Iterator<T>() {
263242
private Node<T> trav = head;
264243

265244
@Override

0 commit comments

Comments
 (0)