diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5ff6309
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d02a3d4
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,95 @@
+
+
+ 4.0.0
+
+ org.example
+ taskCore1
+ 1.0-SNAPSHOT
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.8.1
+ test
+
+
+ org.junit.platform
+ junit-platform-surefire-provider
+ 1.3.2
+
+
+ junit
+ junit
+ 4.12
+ compile
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.8.2
+ compile
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.8.2
+ test
+
+
+ org.example
+ hippodrome
+ 1.0-SNAPSHOT
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.8.2
+ compile
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 4.2.0
+ test
+
+
+ org.mockito
+ mockito-inline
+ 4.2.0
+ test
+
+
+ org.mockito
+ mockito-core
+ 4.2.0
+ compile
+
+
+
+
+
+
+
+ maven-surefire-plugin
+ 2.19.1
+
+
+ org.junit.platform
+ junit-platform-surefire-provider
+ 1.3.2
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java
new file mode 100644
index 0000000..a1187de
--- /dev/null
+++ b/src/main/java/org/example/Main.java
@@ -0,0 +1,32 @@
+package org.example;
+
+
+public class Main {
+ public static void main(String[] args) {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0,"aaa");
+ list.add(1,"eee");
+ list.add(2,"bbb");
+ list.add(3,"rrr");
+ //list.printAll();
+
+ //list.addFirst("yyy");
+ //list.addLast("qqq");
+ //list.printAll();
+
+
+// System.out.println(list.getFirst().getValue());
+// System.out.println(list.getLast().getValue());
+ System.out.println(list.get(1).getValue());
+
+// list.removeFirst();
+// list.printAll();
+
+// list.removeLast();
+// list.printAll();
+
+ // list.remove(2);
+ // list.printAll();
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/example/MyLinkedList.java b/src/main/java/org/example/MyLinkedList.java
new file mode 100644
index 0000000..d70163d
--- /dev/null
+++ b/src/main/java/org/example/MyLinkedList.java
@@ -0,0 +1,136 @@
+package org.example;
+
+public class MyLinkedList {
+
+ private Node first = new Node();
+ private Node last = new Node();
+
+
+ public MyLinkedList() {
+ first.next = last;
+ last.prev = first;
+ }
+
+ public void printAll() {
+ Node current = first.next;
+ while ((current != null) && (current != last)) {
+ System.out.println(current.value);
+ current = current.next;
+ }
+ }
+
+ // size() - returns the size of the list
+ public int size() {
+ Node current = first.next;
+ int count = 0;
+ while ((current != null) && (current != last)) {
+ count++;
+ current = current.next;
+ }
+ return count;
+ }
+
+ // addFirst(el) - adds the element in the beginning of the list
+ public void addFirst(T value) {
+ Node current = new Node();
+ current.value = value;
+ current.prev = first;
+ current.next = first.next;
+ first.next = current;
+ }
+
+ // addLast(el) - adds the element in the end of the list
+ public void addLast(T value) {
+ Node current = new Node();
+ current.value = value;
+ current.prev = last.prev;
+ current.next = last;
+ last.prev.next = current;
+ last.prev = current;
+ }
+
+ // add(index, el) - adds the element in the list by index
+ public void add(int index, T value) {
+ Node current = new Node();
+ current.value = value;
+ Node previous = first;
+ if (index == 0) {
+ current.prev = first;
+ current.next = last;
+
+ first.next = current;
+ last.prev = current;
+ } else {
+ for (int i = 0; i < index; i++) {
+ previous = previous.next;
+ if (previous == last) {
+ throw new StringIndexOutOfBoundsException("Index out of bounds");
+ }
+ }
+ current.prev = previous;
+ current.next = previous.next;
+ previous.next.prev = current;
+ previous.next = current;
+ }
+ }
+
+ // getFirst() - returns the first element of the list
+ public Node getFirst() {
+ return first.next;
+ }
+
+ // getLast() - returns the last element of the list
+ public Node getLast() {
+ return last.prev;
+ }
+
+ // get(index) - returns the element by index
+ public Node get(int index) {
+ Node previous = first;
+ for (int i = 0; i < index; i++) {
+ if (previous == last.prev) {
+ throw new NullPointerException("Index out of bounds");
+ }
+ previous = previous.next;
+ }
+ return previous.next;
+ }
+
+ // removeFirst() - retrieve and remove the first element of the list
+ public void removeFirst() {
+ first.next = first.next.next;
+ first.next.prev = first;
+ }
+
+ // removeLast() - retrieve and remove the last element of the list
+ public void removeLast() {
+ last.prev = last.prev.prev;
+ last.prev.next = last;
+ }
+
+ // remove(index) - retrieve and remove the element of the list by index
+ public void remove(int index) {
+ Node previous = first;
+ for (int i = 0; i < index; i++) {
+ if (previous == last.prev) {
+ throw new NullPointerException("Index out of bounds");
+ }
+ previous = previous.next;
+ }
+ previous.next = previous.next.next;
+ previous.next.prev = previous;
+ }
+
+
+ public static class Node {
+ private Node prev;
+ private T value;
+ private Node next;
+
+ public T getValue() {
+ return value;
+ }
+ }
+
+}
+
diff --git a/src/main/java/org/example/MyLinkedListTest.java b/src/main/java/org/example/MyLinkedListTest.java
new file mode 100644
index 0000000..cae6a2b
--- /dev/null
+++ b/src/main/java/org/example/MyLinkedListTest.java
@@ -0,0 +1,243 @@
+package org.example;
+
+import org.junit.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class MyLinkedListTest {
+ // size() tests
+ @Test
+ public void sizeTest() {
+ MyLinkedList list = new MyLinkedList();
+ assertEquals(0, list.size());
+ }
+
+ @Test
+ public void sizeOfListWithElementsTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.addFirst("YYY");
+ assertEquals(1, list.size());
+ }
+
+ @Test
+ public void sizeOfListWithDeletedElementsTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.removeFirst();
+ assertEquals(0, list.size());
+ }
+
+ // addFirst(el) tests
+ @Test
+ public void addFirstInEmptyListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.addFirst("Y");
+ assertEquals("Y", list.getFirst().getValue());
+ }
+
+ @Test
+ public void addFirstInListWithElementsTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "V");
+ list.add(1, "A");
+ list.addFirst("Y");
+ assertEquals("Y", list.getFirst().getValue());
+ }
+
+ // addLast(el) tests
+ @Test
+ public void addLastInEmptyListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.addLast("Y");
+ assertEquals("Y", list.getLast().getValue());
+ }
+
+ @Test
+ public void addLastInListWithElementsTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "V");
+ list.add(1, "A");
+ list.addLast("Y");
+ assertEquals("Y", list.getLast().getValue());
+ }
+
+ // add(index, el) tests
+ @Test
+ public void whenAddElementWithoutPreviousExceptionTest() {
+ MyLinkedList list = new MyLinkedList();
+ Throwable exception = assertThrows(
+ StringIndexOutOfBoundsException.class,
+ () -> {
+ list.add(1, "Y");
+ }
+ );
+ assertEquals("Index out of bounds", exception.getMessage());
+ }
+
+ @Test
+ public void addInFrontOfListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ assertEquals("Y", list.getFirst().getValue());
+ }
+
+ @Test
+ public void addInMiddleOfListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "V");
+ list.add(1, "A");
+ list.add(2, "R");
+ list.add(3, "C");
+ list.add(2, "Y");
+ assertEquals("Y", list.get(2).getValue());
+ assertEquals("R", list.get(3).getValue());
+ assertEquals("C", list.getLast().getValue());
+ }
+
+ @Test
+ public void addInEndOfListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "V");
+ list.add(1, "A");
+ list.add(2, "R");
+ list.add(3, "Y");
+ assertEquals("Y", list.getLast().getValue());
+ }
+
+ // getFirst() tests
+ @Test
+ public void getFirstFromListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ assertEquals("Y", list.getFirst().getValue());
+
+ list.addFirst("P");
+ assertEquals("P", list.getFirst().getValue());
+ }
+
+ // getLast() tests
+ @Test
+ public void getLastFromListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ assertEquals("R", list.getLast().getValue());
+
+ list.addLast("P");
+ assertEquals("P", list.getLast().getValue());
+ }
+
+ // get(index) tests
+ @Test
+ public void whenGetWithIndexNotExsistingExceptionTest() {
+ MyLinkedList list = new MyLinkedList();
+ Throwable exception = assertThrows(
+ NullPointerException.class,
+ () -> {
+ list.get(5);
+ }
+ );
+ assertEquals("Index out of bounds", exception.getMessage());
+ }
+
+ @Test
+ public void getInFrontOfListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ assertEquals("Y", list.get(0).getValue());
+
+ list.addFirst("T");
+ assertEquals("T", list.get(0).getValue());
+ }
+
+ @Test
+ public void getInMiddleOfListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ assertEquals("R", list.get(1).getValue());
+ }
+
+ @Test
+ public void getInEndOfListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ assertEquals("P", list.get(2).getValue());
+ }
+
+ // removeFirst() tests
+ @Test
+ public void removeFirstFromListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ list.removeFirst();
+ assertEquals("R", list.getFirst().getValue());
+ }
+
+ // removeLast() tests
+ @Test
+ public void removeLastFromListTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ list.add(3, "H");
+ list.removeLast();
+ assertEquals("P", list.getLast().getValue());
+ }
+
+ // remove(index) tests
+ @Test
+ public void whenRemoveNotExsistingElementExceptionTest() {
+ MyLinkedList list = new MyLinkedList();
+ Throwable exception = assertThrows(
+ NullPointerException.class,
+ () -> {
+ list.remove(5);
+ }
+ );
+ assertEquals("Index out of bounds", exception.getMessage());
+ }
+
+ @Test
+ public void removeInFrontOfListByIndexTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ list.add(3, "H");
+ list.remove(0);
+ assertEquals("R", list.get(0).getValue());
+ }
+
+ @Test
+ public void removeInMiddletOfListByIndexTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ list.add(3, "H");
+ list.remove(2);
+ assertEquals("H", list.get(2).getValue());
+ }
+
+ @Test
+ public void removeInEndOfListByIndexTest() {
+ MyLinkedList list = new MyLinkedList();
+ list.add(0, "Y");
+ list.add(1, "R");
+ list.add(2, "P");
+ list.add(3, "H");
+ list.remove(3);
+ assertEquals("P", list.getLast().getValue());
+ }
+
+}