Bael 7408 (#15541)
* BAEL-7408: SinglyLinkedList Example * BAEL-7408: Extract Node interface * BAEL-7408: Setup for WrappedNode LinkedList * BAEL-7408: Removed WrappedNode and cleaned the example * BAEL-7408: Removed Node interface * BAEL-7408: Additional test for removeLast
This commit is contained in:
parent
7f9d025510
commit
506c2cedc1
|
@ -0,0 +1,106 @@
|
|||
package com.baeldung.linkedlistremove;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class SinglyLinkedList<S> {
|
||||
|
||||
private int size;
|
||||
private Node<S> head = null;
|
||||
private Node<S> tail = null;
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void add(S element) {
|
||||
Node<S> newTail = new Node<>(element);
|
||||
if (head == null) {
|
||||
tail = newTail;
|
||||
head = tail;
|
||||
} else {
|
||||
tail.next = newTail;
|
||||
tail = newTail;
|
||||
}
|
||||
++size;
|
||||
}
|
||||
|
||||
public void remove(S element) {
|
||||
if (isEmpty())
|
||||
return;
|
||||
|
||||
Node<S> previous = null;
|
||||
Node<S> current = head;
|
||||
while (current != null) {
|
||||
if (Objects.equals(element, current.element)) {
|
||||
Node<S> next = current.next;
|
||||
if (isFistNode(current)) {
|
||||
head = next;
|
||||
} else if (isLastNode(current)) {
|
||||
previous.next = null;
|
||||
} else {
|
||||
Node<S> next1 = current.next;
|
||||
previous.next = next1;
|
||||
}
|
||||
--size;
|
||||
break;
|
||||
}
|
||||
previous = current;
|
||||
current = current.next;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLast() {
|
||||
if (isEmpty())
|
||||
return;
|
||||
|
||||
if (size() == 1) {
|
||||
tail = null;
|
||||
head = null;
|
||||
} else {
|
||||
Node<S> secondToLast = null;
|
||||
Node<S> last = head;
|
||||
while (last.next != null) {
|
||||
secondToLast = last;
|
||||
last = last.next;
|
||||
}
|
||||
secondToLast.next = null;
|
||||
}
|
||||
--size;
|
||||
}
|
||||
|
||||
public boolean contains(S element) {
|
||||
if (isEmpty())
|
||||
return false;
|
||||
|
||||
Node<S> current = head;
|
||||
while (current != null) {
|
||||
if (Objects.equals(element, current.element))
|
||||
return true;
|
||||
current = current.next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isLastNode(Node<S> node) {
|
||||
return tail == node;
|
||||
}
|
||||
|
||||
private boolean isFistNode(Node<S> node) {
|
||||
return head == node;
|
||||
}
|
||||
|
||||
|
||||
public static class Node<T> {
|
||||
private T element;
|
||||
private Node<T> next;
|
||||
|
||||
public Node(T element) {
|
||||
this.element = element;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.linkedlistremove;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class CreateListProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
return Stream.of(
|
||||
Arguments.of(List.of("January"), 1),
|
||||
Arguments.of(List.of("January", "February"), 2),
|
||||
Arguments.of(List.of("January", "February", "March"), 3),
|
||||
Arguments.of(List.of("January","February","March","April"), 4),
|
||||
Arguments.of(List.of("January","February","March","April","May"), 5),
|
||||
Arguments.of(List.of("January","February","March","April","May","June"), 6),
|
||||
Arguments.of(List.of("January","February","March","April","May","June","July"), 7),
|
||||
Arguments.of(List.of("January","February","March","April","May","June","July","August"), 8),
|
||||
Arguments.of(List.of("January","February","March","April","May","June","July","August","September"), 9),
|
||||
Arguments.of(List.of("January","February","March","April","May","June","July","August","September","October"), 10),
|
||||
Arguments.of(List.of("January","February","March","April","May","June","July","August","September","October","November"), 11),
|
||||
Arguments.of(List.of("January","February","March","April","May","June","July","August","September","October","November","December"), 12)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.linkedlistremove;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class DeleteListProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
return Stream.of(
|
||||
Arguments.of(List.of("Monday"), 6),
|
||||
Arguments.of(List.of("Monday", "Tuesday"), 5),
|
||||
Arguments.of(List.of("Monday", "Tuesday", "Wednesday"), 4),
|
||||
Arguments.of(List.of("Monday", "Tuesday", "Wednesday", "Thursday"), 3),
|
||||
Arguments.of(List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"), 2),
|
||||
Arguments.of(List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), 1),
|
||||
Arguments.of(List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"), 0)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.baeldung.linkedlistremove;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
class SinglyLinkedListUnitTest {
|
||||
|
||||
private SinglyLinkedList<String> linkedList;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
linkedList = new SinglyLinkedList<>();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given an empty list")
|
||||
class GivenEmptyLinkedList {
|
||||
|
||||
|
||||
@Test
|
||||
void whenNewListThenListEmpty() {
|
||||
assertThat(linkedList.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAddElementThenListNotEmpty() {
|
||||
linkedList.add("Hello world!");
|
||||
assertThat(linkedList.isEmpty()).isFalse();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(CreateListProvider.class)
|
||||
void whenAddingElementsThenSizeIsCorrect(List<String> toAdd, int expectedSize) {
|
||||
toAdd.forEach(linkedList::add);
|
||||
assertThat(linkedList.size()).isEqualTo(expectedSize);
|
||||
toAdd.forEach(s -> assertThat(linkedList.contains(s)).isTrue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a filled list")
|
||||
class GivenFilledLinkedList {
|
||||
|
||||
private final List<String> SOURCE =
|
||||
List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
SOURCE.forEach(linkedList::add);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(DeleteListProvider.class)
|
||||
void whenDeleteElementsSizeIsCorrect(List<String> toDelete, int expectedSize) {
|
||||
toDelete.forEach(linkedList::remove);
|
||||
assertThat(linkedList.size()).isEqualTo(expectedSize);
|
||||
toDelete.forEach(s -> assertThat(linkedList.contains(s)).isFalse());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"1,6",
|
||||
"2,5",
|
||||
"3,4",
|
||||
"4,3",
|
||||
})
|
||||
void whenDeleteElementsSizeIsCorrect(int toRemove, int expectedSize) {
|
||||
for (int i = 0; i < toRemove; i++) {
|
||||
linkedList.removeLast();
|
||||
}
|
||||
assertThat(linkedList.size()).isEqualTo(expectedSize);
|
||||
SOURCE.subList(0, expectedSize).forEach(s -> assertThat(linkedList.contains(s)).isTrue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue