From e45f0db68480bb120dc3ed043d69233d73e2cbdf Mon Sep 17 00:00:00 2001 From: Serhii Date: Wed, 13 Jan 2021 17:12:28 +0200 Subject: [PATCH 1/2] GP-33 Add into main --- .../com/bobocode/array_list/ArrayList.java | 211 +++++++++++ .../java/com/bobocode/array_list/README.MD | 17 + .../bobocode/array_list/ArrayListTest.java | 356 ++++++++++++++++++ pom.xml | 1 + 4 files changed, 585 insertions(+) create mode 100644 2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java create mode 100644 2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/README.MD create mode 100644 2-0-data-structures-and-algorithms/src/test/java/com/bobocode/array_list/ArrayListTest.java diff --git a/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java new file mode 100644 index 00000000..e7a3f155 --- /dev/null +++ b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java @@ -0,0 +1,211 @@ +package com.bobocode.array_list; + +import com.bobocode.linked_list.List; + +import java.util.Arrays; +import java.util.NoSuchElementException; +import java.util.Objects; + +/** + * {@link ArrayList} is an implementation of {@link List} interface. This resizable data structure + * based on an array and is simplified version of {@link java.util.ArrayList}. + */ +public class ArrayList implements List { + + public static final int DEFAULT_CAPACITY = 5; + private Object[] elementData; + private int size; + + /** + * This constructor creates an instance of {@link ArrayList} with a specific capacity of an array inside. + * + * @param initCapacity - the initial capacity of the list + * @throws IllegalArgumentException – if the specified initial capacity is negative or 0. + */ + public ArrayList(int initCapacity) { + if (initCapacity > 0) { + elementData = new Object[initCapacity]; + } else { + throw new IllegalArgumentException(); + } + } + + /** + * This constructor creates an instance of {@link ArrayList} with a default capacity of an array inside. + * A default size of inner array is 5; + */ + public ArrayList() { + elementData = new Object[DEFAULT_CAPACITY]; + } + + /** + * Creates and returns an instance of {@link ArrayList} with provided elements + * + * @param elements to add + * @return new instance + */ + public static List of(T... elements) { + List list = new ArrayList<>(elements.length); + for (T element : elements) { + list.add(element); + } + return list; + } + + /** + * Adds an element to the array and returns index of position. + * + * @param element element to add + */ + @Override + public void add(T element) { + increaseDataArrayIfFull(); + elementData[size] = element; + size++; + } + + private void increaseDataArrayIfFull() { + if (elementData.length <= size) { + elementData = getTrimmedArrayToSize(elementData.length * 2); + } + } + + /** + * Adds an element to the specific position in the array where + * + * @param index index of position + * @param element element to add + */ + @Override + public void add(int index, T element) { + increaseDataArrayIfFull(); + System.arraycopy(elementData, index, elementData, index + 1, size - index); + elementData[index] = element; + size++; + } + + /** + * Retrieves an element by its position index. In case provided index in out of the list bounds it + * throws {@link IndexOutOfBoundsException} + * + * @param index index of element + * @return en element + */ + @Override + @SuppressWarnings("unchecked") + public T get(int index) { + Objects.checkIndex(index, size); + return (T) elementData[index]; + } + + /** + * Returns the first element of the list. Operation is performed in constant time O(1) + * + * @return the first element of the list + * @throws java.util.NoSuchElementException if list is empty + */ + @Override + @SuppressWarnings("unchecked") + public T getFirst() { + if (isEmpty()) { + throw new NoSuchElementException(); + } + return (T) elementData[0]; + } + + /** + * Returns the last element of the list. Operation is performed in constant time O(1) + * + * @return the last element of the list + * @throws java.util.NoSuchElementException if list is empty + */ + @Override + @SuppressWarnings("unchecked") + public T getLast() { + if (isEmpty()) { + throw new NoSuchElementException(); + } + return (T) elementData[size - 1]; + } + + /** + * Changes the value of array at specific position. In case provided index in out of the list bounds it + * throws {@link IndexOutOfBoundsException} + * + * @param index position of value + * @param element a new value + */ + @Override + public void set(int index, T element) { + Objects.checkIndex(index, size); + elementData[index] = element; + } + + /** + * Removes an elements by its position index. In case provided index in out of the list bounds it + * throws {@link IndexOutOfBoundsException} + * + * @param index element index + */ + @Override + public void remove(int index) { + if (index == size - 1) { + elementData = getTrimmedArrayToSize(size - 1); + } else { + System.arraycopy(elementData, index + 1, elementData, index, size - index - 1); + } + size--; + } + + /** + * Checks for existing of a specific element in the list. + * + * @param element is element + * @return If element exists method returns true, otherwise it returns false + */ + @Override + public boolean contains(T element) { + if (isEmpty()) { + return false; + } else { + for (Object elem : elementData) { + if (elem.equals(element)) { + return true; + } + } + } + return false; + } + + /** + * Checks if a list is empty + * + * @return {@code true} if list is empty, {@code false} otherwise + */ + @Override + public boolean isEmpty() { + return size == 0; + } + + @SuppressWarnings("unchecked") + private T[] getTrimmedArrayToSize(int size) { + return (T[]) Arrays.copyOf(elementData, size); + } + + /** + * @return amount of saved elements + */ + @Override + public int size() { + return size; + } + + /** + * Removes all list elements + */ + @Override + public void clear() { + elementData = new Object[DEFAULT_CAPACITY]; + size = 0; + } +} diff --git a/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/README.MD b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/README.MD new file mode 100644 index 00000000..d12576e0 --- /dev/null +++ b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/README.MD @@ -0,0 +1,17 @@ +# Array Wrapper exercise :muscle: +Improve your basic knowledge about data structures and Java Core. +This wrapper is a simple version of the `ArrayList` data structure. +### Task +`ListOfLongs` interface provides an API with a couple of methods for a wrapper of a default array in Java. Your job is to implement the *todo* section of `ArrayListOfLongs` class. +To verify your implementation, run `ListOfLongsTest.java`. + +### Pre-conditions :heavy_exclamation_mark: +You're supposed to be familiar with arrays, cycles, conditions, exceptions and variables. + +### How to start :question: +* Just clone the repository and start implementing the **todo** section, verify your changes by running tests +* If you don't have enough knowledge about this domain, check out the [links below](#related-materials-information_source) +* Don't worry if you got stuck, checkout the **exercise/completed** branch and see the final implementation + +### Related materials :information_source: + ###to do \ No newline at end of file diff --git a/2-0-data-structures-and-algorithms/src/test/java/com/bobocode/array_list/ArrayListTest.java b/2-0-data-structures-and-algorithms/src/test/java/com/bobocode/array_list/ArrayListTest.java new file mode 100644 index 00000000..420de3b3 --- /dev/null +++ b/2-0-data-structures-and-algorithms/src/test/java/com/bobocode/array_list/ArrayListTest.java @@ -0,0 +1,356 @@ +package com.bobocode.array_list; + +import com.bobocode.linked_list.List; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +import java.util.NoSuchElementException; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class ArrayListTest { + + private List arrayList = new ArrayList<>(); + + @Test + @Order(1) + public void add() { + arrayList.add(10); + arrayList.add(15); + arrayList.add(20); + + assertThat(arrayList.get(0)).isEqualTo(10); + assertThat(arrayList.get(1)).isEqualTo(15); + assertThat(arrayList.get(2)).isEqualTo(20); + } + + @Test + @Order(2) + public void sizeOfEmptyArrayWrapper() { + assertThat(arrayList.size()).isEqualTo(0); + } + + @Test + @Order(3) + void size() { + arrayList.add(10); + arrayList.add(15); + arrayList.add(20); + + assertThat(arrayList.size()).isEqualTo(3); + } + + + @Test + @Order(4) + public void getElementsByIndex() { + arrayList.add(10); + arrayList.add(15); + arrayList.add(20); + + assertThat(arrayList.get(0)).isEqualTo(10); + assertThat(arrayList.get(1)).isEqualTo(15); + assertThat(arrayList.get(2)).isEqualTo(20); + assertThat(arrayList.size()).isEqualTo(3); + } + + @Test + @Order(5) + public void getFirstElement() { + arrayList = ArrayList.of(31, 32); + + assertThat(arrayList.getFirst()).isEqualTo(31); + + } + + @Test + @Order(6) + public void getLastElement() { + arrayList = ArrayList.of(21, 34); + + assertThat(arrayList.getLast()).isEqualTo(34); + } + + @Test + @Order(7) + public void getFirstOfEmptyList() { + assertThatExceptionOfType(NoSuchElementException.class) + .isThrownBy(() -> arrayList.getFirst()); + } + + @Test + @Order(8) + public void getLastOfEmptyList() { + assertThatExceptionOfType(NoSuchElementException.class) + .isThrownBy(() -> arrayList.getLast()); + } + + @Test + @Order(9) + public void listWithSpecificCapacity() { + arrayList = new ArrayList<>(8); + + arrayList.add(10); + arrayList.add(15); + arrayList.add(20); + + assertThat(arrayList.get(0)).isEqualTo(10); + assertThat(arrayList.get(1)).isEqualTo(15); + assertThat(arrayList.get(2)).isEqualTo(20); + } + + @Test + @Order(10) + public void listWithWrongCapacity() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> arrayList = new ArrayList<>(-2)); + } + + @Test + @Order(11) + public void addElements() { + arrayList = ArrayList.of(15, 69, 58, 78); + + assertThat(arrayList.get(0)).isEqualTo(15); + assertThat(arrayList.get(1)).isEqualTo(69); + assertThat(arrayList.get(2)).isEqualTo(58); + assertThat(arrayList.get(3)).isEqualTo(78); + assertThat(arrayList.size()).isEqualTo(4); + } + + @Test + @Order(12) + public void resizeDefaultCapacity() { + arrayList = new ArrayList<>(); + + arrayList.add(15); + arrayList.add(69); + arrayList.add(58); + arrayList.add(78); + arrayList.add(6); + arrayList.add(33); + arrayList.add(21); + + assertThat(arrayList.get(6)).isEqualTo(21); + assertThat(arrayList.size()).isEqualTo(7); + } + + @Test + @Order(13) + public void resizeSpecificCapacity() { + arrayList = new ArrayList<>(4); + + arrayList.add(15); + arrayList.add(69); + arrayList.add(58); + arrayList.add(78); + arrayList.add(6); + arrayList.add(33); + arrayList.add(21); + + assertThat(arrayList.get(6)).isEqualTo(21); + assertThat(arrayList.size()).isEqualTo(7); + } + + @Test + @Order(14) + public void addElementByIndex() { + arrayList = ArrayList.of(15, 69, 58, 78, 68); + + arrayList.add(50); + arrayList.add(2, 10); + + assertThat(arrayList.get(2)).isEqualTo(10); + assertThat(arrayList.get(5)).isEqualTo(68); + assertThat(arrayList.size()).isEqualTo(7); + } + + @Test + @Order(15) + public void addElementByNegativeIndex() { + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.add(-1, 66)); + + } + + @Test + @Order(16) + public void addElementByIndexLargerThanListSize() { + arrayList = ArrayList.of(4, 6, 11, 9); + + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.add(5, 88)); + } + + @Test + @Order(17) + public void addElementByIndexEqualToSize() { + arrayList = ArrayList.of(1, 2, 3, 4, 5); // size = 5 + + arrayList.add(5, 111); + + assertThat(arrayList.get(5)).isEqualTo(111); + assertThat(arrayList.size()).isEqualTo(6); + } + + @Test + @Order(18) + public void getFirstElementFromEmptyList() { + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.get(0)); + } + + @Test + @Order(19) + public void getElementByNegativeIndex() { + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.get(-1)); + } + + @Test + @Order(20) + public void getElementByIndexEqualToListSize() { + arrayList = ArrayList.of(15, 69, 58, 78); + + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.get(4)); + } + + @Test + @Order(21) + public void setElementByIndex() { + arrayList = ArrayList.of(15, 69, 58, 78); + + arrayList.set(2, 10); + + assertThat(arrayList.get(2)).isEqualTo(10); + assertThat(arrayList.get(3)).isEqualTo(78); + assertThat(arrayList.size()).isEqualTo(4); + } + + @Test + @Order(22) + public void setElementByIndexEqualToSize() { + arrayList = ArrayList.of(15, 69, 58, 78); + + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.set(4, 10)); + } + + @Test + @Order(23) + public void setFirstElementOnEmptyTree() { + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.set(0, 34)); + } + + @Test + @Order(24) + public void removeElementByIndex() { + arrayList = ArrayList.of(15, 69, 58, 78, 100); + + arrayList.remove(2); + + assertThat(arrayList.get(2)).isEqualTo(78); + assertThat(arrayList.get(1)).isEqualTo(69); + assertThat(arrayList.size()).isEqualTo(4); + } + + @Test + @Order(25) + public void removeElementByIndexEqualToSize() { + arrayList = ArrayList.of(15, 69, 58, 78); + + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.remove(4)); + } + + @Test + @Order(26) + public void removeLastElementByIndex() { + arrayList = ArrayList.of(15, 69, 58, 78, 100); + + arrayList.remove(4); + + assertThat(arrayList.get(3)).isEqualTo(78); + assertThat(arrayList.size()).isEqualTo(4); + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.get(4)); + } + + @Test + @Order(27) + public void removeElementByIndexOutOfBounds() { + arrayList = ArrayList.of(15, 69, 58, 78, 100); + + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.remove(6)); + } + + @Test + @Order(28) + public void containsOnEmptyList() { + assertThat(arrayList.contains(8)).isEqualTo(false); + } + + @Test + @Order(29) + public void containsElement() { + arrayList = ArrayList.of(15, 69, 58, 78, 100); + + assertThat(arrayList.contains(58)).isEqualTo(true); + } + + @Test + @Order(30) + public void findNotExistingElement() { + arrayList = ArrayList.of(15, 69, 58, 78, 100); + + assertThat(arrayList.contains(200)).isEqualTo(false); + } + + @Test + @Order(31) + public void isEmptyOnEmptyList() { + assertThat(arrayList.isEmpty()).isEqualTo(true); + } + + @Test + @Order(32) + public void isEmpty() { + arrayList = ArrayList.of(34, 5, 6); + + assertThat(arrayList.isEmpty()).isEqualTo(false); + } + + @Test + @Order(33) + public void clearOnEmptyList() { + assertThat(arrayList.isEmpty()).isEqualTo(true); + } + + @Test + @Order(34) + public void clearChangesTheSize() { + arrayList = ArrayList.of(4, 5, 6); + + arrayList.clear(); + + assertThat(arrayList.size()).isEqualTo(0); + } + + @Test + @Order(35) + public void clearRemovesElements() { + arrayList = ArrayList.of(4, 5, 6); + + arrayList.clear(); + + assertThatExceptionOfType(IndexOutOfBoundsException.class) + .isThrownBy(() -> arrayList.get(0)); + } +} diff --git a/pom.xml b/pom.xml index 43c0946f..aeb00a04 100644 --- a/pom.xml +++ b/pom.xml @@ -73,4 +73,5 @@ + \ No newline at end of file From 0341f6585cb60dea138e5ef88d4465ba90fda55b Mon Sep 17 00:00:00 2001 From: Serhii Date: Wed, 13 Jan 2021 18:01:33 +0200 Subject: [PATCH 2/2] GP-33 Redo completed methods for main --- .../com/bobocode/array_list/ArrayList.java | 87 ++++--------------- 1 file changed, 15 insertions(+), 72 deletions(-) diff --git a/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java index e7a3f155..81de865a 100644 --- a/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java +++ b/2-0-data-structures-and-algorithms/src/main/java/com/bobocode/array_list/ArrayList.java @@ -1,10 +1,7 @@ package com.bobocode.array_list; import com.bobocode.linked_list.List; - -import java.util.Arrays; -import java.util.NoSuchElementException; -import java.util.Objects; +import com.bobocode.util.ExerciseNotCompletedException; /** * {@link ArrayList} is an implementation of {@link List} interface. This resizable data structure @@ -12,10 +9,6 @@ */ public class ArrayList implements List { - public static final int DEFAULT_CAPACITY = 5; - private Object[] elementData; - private int size; - /** * This constructor creates an instance of {@link ArrayList} with a specific capacity of an array inside. * @@ -23,11 +16,7 @@ public class ArrayList implements List { * @throws IllegalArgumentException – if the specified initial capacity is negative or 0. */ public ArrayList(int initCapacity) { - if (initCapacity > 0) { - elementData = new Object[initCapacity]; - } else { - throw new IllegalArgumentException(); - } + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -35,7 +24,7 @@ public ArrayList(int initCapacity) { * A default size of inner array is 5; */ public ArrayList() { - elementData = new Object[DEFAULT_CAPACITY]; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -45,11 +34,7 @@ public ArrayList() { * @return new instance */ public static List of(T... elements) { - List list = new ArrayList<>(elements.length); - for (T element : elements) { - list.add(element); - } - return list; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -59,15 +44,7 @@ public static List of(T... elements) { */ @Override public void add(T element) { - increaseDataArrayIfFull(); - elementData[size] = element; - size++; - } - - private void increaseDataArrayIfFull() { - if (elementData.length <= size) { - elementData = getTrimmedArrayToSize(elementData.length * 2); - } + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -78,10 +55,7 @@ private void increaseDataArrayIfFull() { */ @Override public void add(int index, T element) { - increaseDataArrayIfFull(); - System.arraycopy(elementData, index, elementData, index + 1, size - index); - elementData[index] = element; - size++; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -92,10 +66,8 @@ public void add(int index, T element) { * @return en element */ @Override - @SuppressWarnings("unchecked") public T get(int index) { - Objects.checkIndex(index, size); - return (T) elementData[index]; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -105,12 +77,8 @@ public T get(int index) { * @throws java.util.NoSuchElementException if list is empty */ @Override - @SuppressWarnings("unchecked") public T getFirst() { - if (isEmpty()) { - throw new NoSuchElementException(); - } - return (T) elementData[0]; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -120,12 +88,8 @@ public T getFirst() { * @throws java.util.NoSuchElementException if list is empty */ @Override - @SuppressWarnings("unchecked") public T getLast() { - if (isEmpty()) { - throw new NoSuchElementException(); - } - return (T) elementData[size - 1]; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -137,8 +101,7 @@ public T getLast() { */ @Override public void set(int index, T element) { - Objects.checkIndex(index, size); - elementData[index] = element; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -149,12 +112,7 @@ public void set(int index, T element) { */ @Override public void remove(int index) { - if (index == size - 1) { - elementData = getTrimmedArrayToSize(size - 1); - } else { - System.arraycopy(elementData, index + 1, elementData, index, size - index - 1); - } - size--; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -165,16 +123,7 @@ public void remove(int index) { */ @Override public boolean contains(T element) { - if (isEmpty()) { - return false; - } else { - for (Object elem : elementData) { - if (elem.equals(element)) { - return true; - } - } - } - return false; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -184,12 +133,7 @@ public boolean contains(T element) { */ @Override public boolean isEmpty() { - return size == 0; - } - - @SuppressWarnings("unchecked") - private T[] getTrimmedArrayToSize(int size) { - return (T[]) Arrays.copyOf(elementData, size); + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -197,7 +141,7 @@ private T[] getTrimmedArrayToSize(int size) { */ @Override public int size() { - return size; + throw new ExerciseNotCompletedException(); // todo: implement this method } /** @@ -205,7 +149,6 @@ public int size() { */ @Override public void clear() { - elementData = new Object[DEFAULT_CAPACITY]; - size = 0; + throw new ExerciseNotCompletedException(); // todo: implement this method } }