From 9329d5d7780a0c279a4b2a1b7357a13f4731e045 Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 5 Jan 2021 15:59:53 +0200 Subject: [PATCH] GP-26 add the exercise solution with a tail and extra methods --- .../com/bobocode/linked_list/LinkedList.java | 126 ++++++++++++++++-- 1 file changed, 112 insertions(+), 14 deletions(-) diff --git a/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/linked_list/LinkedList.java b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/linked_list/LinkedList.java index f0a80833..f44843f4 100644 --- a/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/linked_list/LinkedList.java +++ b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/linked_list/LinkedList.java @@ -1,7 +1,8 @@ package com.bobocode.linked_list; - -import com.bobocode.util.ExerciseNotCompletedException; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.stream.Stream; /** * {@link LinkedList} is a list implementation that is based on singly linked generic nodes. A node is implemented as @@ -10,6 +11,9 @@ * @param generic type parameter */ public class LinkedList implements List { + private Node head; + private Node tail; + private int size; /** * This method creates a list of provided elements @@ -19,7 +23,9 @@ public class LinkedList implements List { * @return a new list of elements the were passed as method parameters */ public static List of(T... elements) { - throw new ExerciseNotCompletedException(); // todo: implement this method + LinkedList linkedList = new LinkedList<>(); + Stream.of(elements).forEach(linkedList::add); + return linkedList; } /** @@ -29,7 +35,7 @@ public static List of(T... elements) { */ @Override public void add(T element) { - throw new ExerciseNotCompletedException(); // todo: implement this method + add(size, element); } /** @@ -41,7 +47,51 @@ public void add(T element) { */ @Override public void add(int index, T element) { - throw new ExerciseNotCompletedException(); // todo: implement this method + Node newNode = Node.valueOf(element); + if (index == 0) { + addAsHead(newNode); + } else if (index == size) { + addAsTail(newNode); + } else { + add(index, newNode); + } + size++; + } + + private void addAsHead(Node newNode) { + newNode.next = head; + head = newNode; + if (head.next == null) { + tail = head; + } + } + + private void addAsTail(Node newNode) { + tail.next = newNode; + tail = newNode; + } + + private void add(int index, Node newNode) { + Node node = findNodeByIndex(index - 1); + newNode.next = node.next; + node.next = newNode; + } + + private Node findNodeByIndex(int index) { + Objects.checkIndex(index, size); + if (index == size - 1) { + return tail; + } else { + return nodeAt(index); + } + } + + private Node nodeAt(int index) { + Node currentNode = head; + for (int i = 0; i < index; i++) { + currentNode = currentNode.next; + } + return currentNode; } /** @@ -53,7 +103,8 @@ public void add(int index, T element) { */ @Override public void set(int index, T element) { - throw new ExerciseNotCompletedException(); // todo: implement this method + Node node = findNodeByIndex(index); + node.value = element; } /** @@ -65,7 +116,8 @@ public void set(int index, T element) { */ @Override public T get(int index) { - throw new ExerciseNotCompletedException(); // todo: implement this method + Node node = findNodeByIndex(index); + return node.value; } /** @@ -76,7 +128,8 @@ public T get(int index) { */ @Override public T getFirst() { - throw new ExerciseNotCompletedException(); // todo: implement this method + checkElementsExist(); + return head.value; } /** @@ -87,7 +140,14 @@ public T getFirst() { */ @Override public T getLast() { - throw new ExerciseNotCompletedException(); // todo: implement this method + checkElementsExist(); + return tail.value; + } + + private void checkElementsExist() { + if (head == null) { + throw new NoSuchElementException(); + } } /** @@ -95,12 +155,29 @@ public T getLast() { * throws {@link IndexOutOfBoundsException} * * @param index element index + * @return an element value */ @Override public void remove(int index) { - throw new ExerciseNotCompletedException(); // todo: implement this method + if (index == 0) { + Objects.checkIndex(index, size); + removeHead(); + } else { + Node previousNode = findNodeByIndex(index - 1); + previousNode.next = previousNode.next.next; + if (index == size - 1) { + tail = previousNode; + } + } + size--; } + private void removeHead() { + head = head.next; + if (head == null) { + tail = null; + } + } /** * Checks if a specific exists in he list @@ -109,7 +186,14 @@ public void remove(int index) { */ @Override public boolean contains(T element) { - throw new ExerciseNotCompletedException(); // todo: implement this method + Node currentNode = head; + while (currentNode != null) { + if (currentNode.value.equals(element)) { + return true; + } + currentNode = currentNode.next; + } + return false; } /** @@ -119,7 +203,7 @@ public boolean contains(T element) { */ @Override public boolean isEmpty() { - throw new ExerciseNotCompletedException(); // todo: implement this method + return head == null; } /** @@ -129,7 +213,7 @@ public boolean isEmpty() { */ @Override public int size() { - throw new ExerciseNotCompletedException(); // todo: implement this method + return size; } /** @@ -137,6 +221,20 @@ public int size() { */ @Override public void clear() { - throw new ExerciseNotCompletedException(); // todo: implement this method + head = tail = null; + size = 0; + } + + static class Node { + private T value; + private Node next; + + private Node(T value) { + this.value = value; + } + + public static Node valueOf(T value) { + return new Node<>(value); + } } }