낭만개발자
낭만개발자
낭만개발자
전체 방문자
오늘
어제
  • 분류 전체보기 (57)
    • Web) HTML & CSS (5)
    • Web) HTTP (2)
    • 언어) Java (2)
    • 언어) Python (6)
    • 언어) PHP (1)
    • Linux (2)
    • 데이터 관리) Pandas (4)
    • Algorithms (13)
    • 개발자 역량 (4)
    • 프로젝트 (14)
      • Django 초기 프로젝트 (1)
      • CatCoDog _ 반려동물 식품 판매 사이트 (9)
      • 개인 홈서버 프로젝트 (2)
      • 이력핏 : AI가 추천해주는 이력서 (2)
    • 문제와 사고 (2)
    • ETC (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • css basic
  • Java
  • 웹개발
  • dp
  • algorithm
  • 오늘의 문제
  • Unique Paths
  • django setting
  • rainbow table
  • python
  • leetcode88
  • 파이썬
  • Number Of Island
  • catcodog
  • css 기본
  • python basic
  • css
  • 파이썬 숫자형
  • 파이썬 기초
  • 파이썬 자료형
  • WEB
  • css 포지션
  • 장고 초기 세팅
  • python operator
  • Leetcode
  • Merge Sorted Array
  • 리눅스
  • JWT 웹
  • 파이썬 기본
  • css 위치변경

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
낭만개발자

낭만개발자

카테고리 없음

[DataStructure] Dynamic Array 구현 (with Java, TDD)

2024. 7. 21. 03:22

DynamicArray.java

import java.util.ArrayList;
import java.util.Arrays;

public class DynamicArray implements List {
    protected static final int DEFAULT_CAPACITY = 16;
    protected static final String INDEX_BOUNDS_ERROR_MESSAGE = "The index must be gte to zero and lte to size";

    private int size;
    private int capacity;
    private int[] elements;

    public DynamicArray() {
        this(DEFAULT_CAPACITY);
    }

    public DynamicArray(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        this.elements = new int[capacity];
    }

    @Override
    public void add(int value) {
        ensureCapacity();
        elements[size++] = value;
    }

    @Override
    public void add(int index, int value) {
        ensureCapacity();
        ensureIndexBounds(index);
        System.arraycopy(elements, index, elements, index + 1, size - index);
        elements[index] = value;
        size++;
    }

    @Override
    public void remove(int index) {
        ensureIndexBounds(index);
        System.arraycopy(elements, index + 1, elements, index, size - index - 1);
        size--;
    }

    @Override
    public int indexOf(int value) {
        for (int i = 0; i < size; i++) {
            if (elements[i] == value) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public int lastIndexOf(int value) {
        for (int i = size - 1; i >= 0; i--) {
            if (elements[i] == value) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public int get(int index) {
        ensureIndexBounds(index);
        return elements[index];
    }

    @Override
    public void set(int index, int value) {
        ensureIndexBounds(index);
        elements[index] = value;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean contains(int value) {
        for (int i = 0; i < size; i++) {
            if (elements[i] == value) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void clear() {
        this.size = 0;
        Arrays.fill(elements, 0);
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public int[] toArray() {
        int[] result = new int[size];
        System.arraycopy(elements, 0, result, 0, size);
        return result;
    }

    private void ensureIndexBounds(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException(INDEX_BOUNDS_ERROR_MESSAGE);
        }
    }
    private void ensureCapacity() {
        if (size == capacity) {
            int[] newElements = new int[capacity * 2];
            System.arraycopy(elements, 0, newElements, 0, size);
            elements = newElements;
            capacity *= 2;
        }
    }
}

 

List.java (Interface)

public interface List {
    void add(int value);
    void add(int index, int value);
    void remove(int index);
    int get(int index);
    int indexOf(int value);
    int lastIndexOf(int value);
    void set(int index, int value);
    int size();
    boolean isEmpty();
    boolean contains(int value);
    void clear();
    int[] toArray();
}

 

DynamicArrayTest.java (Test Code)

package com.kyle.ds.list;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;

class DynamicArrayTest {
    public static Stream<Arguments> provideContains() {
        return Stream.of(
                Arguments.of(Arrays.asList(1, 2, 3), 1, true),
                Arguments.of(Arrays.asList(1, 2, 3), 4, false)
        );
    }

    @Test
    void shouldReturnAsAnArray() {
        List dynamicArray = new DynamicArray();

        int[] expected = new int[0];
        int[] result = dynamicArray.toArray();

        assertEquals(expected.length, result.length);
    }

    @ParameterizedTest
    @ValueSource(ints = {1, 5, 10, 17, 26, 50, 100, 1000, 10000, 100000})
    void shouldReturnAnArrayIncludingExpectedElement(int size) {
        List dynamicArray = new DynamicArray();

        // [0, 1, 2, 3, 4]
        int[] expected = IntStream.range(0, size).toArray();

        for (int element : expected) {
            dynamicArray.add(element);
        }

        int[] result = dynamicArray.toArray();

        assertEquals(expected.length, result.length);
        for (int i = 0; i < expected.length; i++) {
            assertEquals(expected[i], result[i]);
        }
    }

    @Test
    void shouldRemoveTheElement() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        dynamicArray.remove(1);

        int[] expected = {1, 3};
        int[] result = dynamicArray.toArray();

        assertEquals(expected.length, result.length);
        for (int i = 0; i < expected.length; i++) {
            assertEquals(expected[i], result[i]);
        }
    }

    @ParameterizedTest
    @ValueSource(ints = {-1, 0})
    void shouldThrowIndexOutOfBoundsException(int index) {
        List dynamicArray = new DynamicArray();

        IndexOutOfBoundsException indexOutOfBoundsException =
                assertThrows(IndexOutOfBoundsException.class, () -> dynamicArray.remove(index));

        assertEquals(DynamicArray.INDEX_BOUNDS_ERROR_MESSAGE, indexOutOfBoundsException.getMessage());
    }

    @Test
    void shouldReturnTrueWhenThereIsNoElement() {
        List dynamicArray = new DynamicArray();

        boolean result = dynamicArray.isEmpty();

        assertTrue(result);
    }

    @Test
    void shouldReturnFalseWhenThereIsAnyElements() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);

        boolean result = dynamicArray.isEmpty();

        assertFalse(result);
    }

    @ParameterizedTest
    @MethodSource("com.kyle.ds.list.DynamicArrayTest#provideContains")
    void shouldReturnTrueWhenThereIsTheElement(Iterable<Integer> elements, int target, boolean expected) {
        List dynamicArray = new DynamicArray();

        for (int element : elements) {
            dynamicArray.add(element);
        }

        boolean result = dynamicArray.contains(target);

        assertEquals(expected, result);
    }

    @Test
    void shouldClearAllElements() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        dynamicArray.clear();

        int[] expected = new int[0];
        int[] result = dynamicArray.toArray();

        assertEquals(expected.length, result.length);
    }

    @Test
    void shouldReturnTheFirstIndexOfTheElement() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        int expected = 1;
        int result = dynamicArray.indexOf(2);

        assertEquals(expected, result);
    }

    @Test
    void indexOfShouldReturnMinusOneWhenThereIsNoSuchElement() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        int expected = -1;
        int result = dynamicArray.indexOf(4);

        assertEquals(expected, result);
    }

    @Test
    void shouldReturnTheLastIndexOfTheElement() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);
        dynamicArray.add(2);

        int expected = 3;
        int result = dynamicArray.lastIndexOf(2);

        assertEquals(expected, result);
    }

    @Test
    void lastIndexOfShouldReturnMinusOneWhenThereIsNoSuchElement() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        int expected = -1;
        int result = dynamicArray.lastIndexOf(4);

        assertEquals(expected, result);
    }

    @Test
    void shouldSetTheElement() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        dynamicArray.set(1, 4);

        int[] expected = {1, 4, 3};
        int[] result = dynamicArray.toArray();

        assertEquals(expected.length, result.length);
        for (int i = 0; i < expected.length; i++) {
            assertEquals(expected[i], result[i]);
        }
    }

    @ParameterizedTest
    @ValueSource(ints = {-1, 3})
    void shouldThrowIndexOutOfBoundsExceptionWhenSet(int index) {
        List dynamicArray = new DynamicArray();

        IndexOutOfBoundsException indexOutOfBoundsException =
                assertThrows(IndexOutOfBoundsException.class, () -> dynamicArray.set(index, 1));

        assertEquals(DynamicArray.INDEX_BOUNDS_ERROR_MESSAGE, indexOutOfBoundsException.getMessage());
    }

    @Test
    void shouldAddElementToTheIndex() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);
        dynamicArray.add(1, 4);

        int[] expected = {1, 4, 2, 3};
        int[] result = dynamicArray.toArray();

        assertEquals(expected.length, result.length);
        for (int i = 0; i < expected.length; i++) {
            assertEquals(expected[i], result[i]);
        }
    }

    @Test
    void shouldAddElementToTheEndWhenTheListContainsMoreThanDefaultCapacity() {
        List dynamicArray = new DynamicArray();

        for (int i = 0, size = DynamicArray.DEFAULT_CAPACITY + 1; i < size; i++) {
            dynamicArray.add(i);
        }

        int expected = 4;

        dynamicArray.add(1, expected);

        assertEquals(expected, dynamicArray.toArray()[1]);
    }

    @ParameterizedTest
    @ValueSource(ints = {-1, 4})
    void shouldThrowIndexOutOfBoundsExceptionWhenAdd(int index) {
        List dynamicArray = new DynamicArray();

        IndexOutOfBoundsException indexOutOfBoundsException =
                assertThrows(IndexOutOfBoundsException.class, () -> dynamicArray.add(index, 1));

        String expectedMessage = "The index must be gte to zero and lte to size";
        assertEquals(expectedMessage, indexOutOfBoundsException.getMessage());
    }

    @Test
    void shouldReturnTheElementAtTheIndex() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        int expected = 2;
        int result = dynamicArray.get(1);

        assertEquals(expected, result);
    }

    @ParameterizedTest
    @ValueSource(ints = {-1, 3})
    void shouldThrowIndexOutOfBoundsExceptionWhenGet(int index) {
        List dynamicArray = new DynamicArray();

        IndexOutOfBoundsException indexOutOfBoundsException =
                assertThrows(IndexOutOfBoundsException.class, () -> dynamicArray.get(index));

        assertEquals(DynamicArray.INDEX_BOUNDS_ERROR_MESSAGE, indexOutOfBoundsException.getMessage());
    }

    @Test
    void shouldReturnTheSize() {
        List dynamicArray = new DynamicArray();

        dynamicArray.add(1);
        dynamicArray.add(2);
        dynamicArray.add(3);

        int expected = 3;
        int result = dynamicArray.size();

        assertEquals(expected, result);
    }
}
저작자표시 (새창열림)
    낭만개발자
    낭만개발자
    Learning By Doing!💪

    티스토리툴바