diff --git a/src/main/java/List/LinkedList/LinkedList_hellomatia.java b/src/main/java/List/LinkedList/LinkedList_hellomatia.java new file mode 100644 index 0000000..503ea5d --- /dev/null +++ b/src/main/java/List/LinkedList/LinkedList_hellomatia.java @@ -0,0 +1,113 @@ +package List.LinkedList; + +import List.List; + +public class LinkedList_hellomatia implements List { + private final Node head; + private Node tail; + private int size; + + public LinkedList_hellomatia() { + this.head = new Node(null); + this.tail = head; + } + + @Override + public void insert(E data) { + tail.setNext(createNode(data)); + tail = tail.getNext(); + size++; + } + + private Node createNode(E data) { + return new Node(data); + } + + @Override + public int size() { + return size; + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public boolean contains(E o) { + for (Node now = head.getNext(); now != null; now = now.getNext()) { + if (now.getData().equals(o)) { + return true; + } + } + return false; + } + + @Override + public E get(int index) { + checkIndex(index); + return getNode(index).getData(); + } + + @Override + public E remove(int index) { + checkIndex(index); + Node removeNode = getNode(index); + Node prevNode = getNode(index - 1); + if (removeNode == tail) { + prevNode.setNext(null); + tail = prevNode; + } else { + prevNode.setNext(removeNode.getNext()); + } + removeNode.setNext(null); + size--; + return removeNode.getData(); + } + + private void checkIndex(int index) { + if (index < 0 || index >= size()) { + throw new IndexOutOfBoundsException(); + } + } + + private Node getNode(int index) { + Node now = head.getNext(); + for (int i = 0; i < index; i++) { + now = now.getNext(); + } + return now; + } + + public int search(E data) { + int index = 0; + for (Node now = head.getNext(); now != null; now = now.getNext()) { + if (now.getData().equals(data)) { + return index; + } + ++index; + } + return -1; + } + + private class Node { + private final E data; + private Node next; + + protected Node(E data) { + this.data = data; + } + + private Node getNext() { + return next; + } + + private void setNext(Node next) { + this.next = next; + } + + private E getData() { + return data; + } + } +} diff --git a/src/main/java/Stack/StackFactory.java b/src/main/java/Stack/StackFactory.java index 8be7191..6e594a1 100644 --- a/src/main/java/Stack/StackFactory.java +++ b/src/main/java/Stack/StackFactory.java @@ -4,11 +4,11 @@ public class StackFactory { // 자기 클래스 명으로 변경 @SuppressWarnings({ "unchecked", "rawtypes" }) public static Stack createStack_arr() { - return new StackImpl_array_name(); + return new Stack_array_hellomatia(); } @SuppressWarnings({ "unchecked", "rawtypes" }) public static Stack createStack_list() { - return new StackImpl_list_name(); + return new Stack_list_hellomatia(); } } \ No newline at end of file diff --git a/src/main/java/Stack/Stack_array_hellomatia.java b/src/main/java/Stack/Stack_array_hellomatia.java new file mode 100644 index 0000000..d69ff9c --- /dev/null +++ b/src/main/java/Stack/Stack_array_hellomatia.java @@ -0,0 +1,88 @@ +package Stack; + +import java.util.EmptyStackException; + +public class Stack_array_hellomatia implements Stack { + private static final int INITIAL_CAPACITY = 10; + private E[] array; + private int size; + private int maxCapacity; + + @SuppressWarnings("unchecked") + public Stack_array_hellomatia() { + array = (E[]) new Object[INITIAL_CAPACITY]; + this.maxCapacity = INITIAL_CAPACITY; + } + + @Override + public void push(E item) { + if (isNull(item)) { + throw new NullPointerException("Can not push null to the stack"); + } + if (isFull()) { + resize(); + } + array[size()] = item; + ++size; + } + + @Override + public E pop() { + if (isEmpty()) { + throw new EmptyStackException(); + } + return array[top()]; + } + + @Override + public E peek() { + if (isEmpty()) { + throw new EmptyStackException(); + } + return array[size() - 1]; + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public int size() { + return size; + } + + @Override + public int search(E item) { + for (int index = 0; index < size(); ++index) { + if (array[index].equals(item)) { + return index; + } + } + return -1; + } + + private boolean isNull(E item) { + return item == null; + } + + private int top() { + --size; + return size; + } + + private boolean isFull() { + if (size() == Integer.MAX_VALUE) { + throw new OutOfMemoryError(); + } + return maxCapacity == size(); + } + + private void resize() { + maxCapacity = maxCapacity << 1; + @SuppressWarnings("unchecked") + E[] newArray = (E[]) new Object[maxCapacity]; + System.arraycopy(array, 0, newArray, 0, size()); + array = newArray; + } +} diff --git a/src/main/java/Stack/Stack_list_hellomatia.java b/src/main/java/Stack/Stack_list_hellomatia.java new file mode 100644 index 0000000..3904b7d --- /dev/null +++ b/src/main/java/Stack/Stack_list_hellomatia.java @@ -0,0 +1,69 @@ +package Stack; + +import List.LinkedList.LinkedList_hellomatia; + +import java.util.EmptyStackException; + +public class Stack_list_hellomatia implements Stack { + private final LinkedList_hellomatia list; + + public Stack_list_hellomatia() { + list = new LinkedList_hellomatia<>(); + } + + @Override + public void push(E item) { + if (isNull(item)) { + throw new NullPointerException("Can not push null to the stack"); + } + validateSize(); + list.insert(item); + } + + @Override + public E pop() { + if (isEmpty()) { + throw new EmptyStackException(); + } + E item = list.get(top()); + list.remove(top()); + return item; + } + + @Override + public E peek() { + if (isEmpty()) { + throw new EmptyStackException(); + } + return list.get(top()); + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public int size() { + return list.size(); + } + + @Override + public int search(E item) { + return list.search(item); + } + + private boolean isNull(E item) { + return item == null; + } + + private int top() { + return size() - 1; + } + + private void validateSize() { + if (size() == Integer.MAX_VALUE) { + throw new OutOfMemoryError(); + } + } +} diff --git a/src/test/java/Stack/StackTest_hellomatia.java b/src/test/java/Stack/StackTest_hellomatia.java new file mode 100644 index 0000000..8ca4185 --- /dev/null +++ b/src/test/java/Stack/StackTest_hellomatia.java @@ -0,0 +1,100 @@ +package Stack; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.EmptyStackException; + +import static org.junit.jupiter.api.Assertions.*; + +public class StackTest_hellomatia { + private Stack stack_arr; + private Stack stack_list; + + @BeforeEach + void setUp() { + stack_arr = StackFactory.createStack_arr(); + stack_list = StackFactory.createStack_list(); + } + + @Test + public void testPushAndPop() { + stack_arr.push(1); + assertEquals(1, stack_arr.pop()); + stack_list.push(1); + assertEquals(1, stack_list.pop()); + } + + @Test + public void testIsEmpty() { + assertTrue(stack_arr.isEmpty()); + assertTrue(stack_list.isEmpty()); + stack_arr.push(1); + assertFalse(stack_arr.isEmpty()); + stack_list.push(1); + assertFalse(stack_list.isEmpty()); + } + + @Test + public void testPeek() { + stack_arr.push(1); + stack_arr.push(2); + assertEquals(2, stack_arr.peek()); + stack_list.push(1); + stack_list.push(2); + assertEquals(2, stack_list.peek()); + } + + @Test + public void testSize() { + assertEquals(0, stack_arr.size()); + assertEquals(0, stack_list.size()); + stack_arr.push(1); + stack_arr.push(2); + assertEquals(2, stack_arr.size()); + stack_list.push(1); + stack_list.push(2); + assertEquals(2, stack_list.size()); + } + + // 엣지 케이스 테스트 추가 + @Test + public void testPopOnEmptyStack() { + assertThrows(EmptyStackException.class, () -> stack_arr.pop()); + assertThrows(EmptyStackException.class, () -> stack_list.pop()); + } + + @Test + public void testPeekOnEmptyStack() { + assertThrows(EmptyStackException.class, () -> stack_arr.peek()); + assertThrows(EmptyStackException.class, () -> stack_list.peek()); + } + + @Test + public void testPushNull() { + assertThrows(NullPointerException.class, () -> stack_arr.push(null)); + assertThrows(NullPointerException.class, () -> stack_list.push(null)); + } + + @Test + public void testPushBeyondMaxSize() { + try { + // Integer.MAX_VALUE - 2까지 채우기 + for (int i = 0; i < Integer.MAX_VALUE - 2; i++) { + stack_arr.push(i); +// stack_list.push(i); + } + // 여기서 한 번 더 push 하려고 할 때 + stack_arr.push(Integer.MAX_VALUE - 1); +// stack_list.push(Integer.MAX_VALUE - 1); + // 예외가 발생하지 않으면 테스트 실패 + fail("Should have thrown OutOfMemoryError or similar"); + } catch (OutOfMemoryError e) { + // 예상되는 예외 처리 + assertTrue(true, "Expected OutOfMemoryError when pushing beyond max size"); + } catch (Exception e) { + // 다른 예외 발생 시 + fail("Unexpected exception type: " + e); + } + } +} \ No newline at end of file diff --git a/src/test/java/Stack/StackTest_name.java b/src/test/java/Stack/StackTest_name.java index f7e2514..8310cdd 100644 --- a/src/test/java/Stack/StackTest_name.java +++ b/src/test/java/Stack/StackTest_name.java @@ -80,11 +80,11 @@ public void testPushBeyondMaxSize() { // Integer.MAX_VALUE - 2까지 채우기 for (int i = 0; i < Integer.MAX_VALUE - 2; i++) { stack_arr.push(i); - stack_list.push(i); +// stack_list.push(i); } // 여기서 한 번 더 push 하려고 할 때 stack_arr.push(Integer.MAX_VALUE - 1); - stack_list.push(Integer.MAX_VALUE - 1); +// stack_list.push(Integer.MAX_VALUE - 1); // 예외가 발생하지 않으면 테스트 실패 fail("Should have thrown OutOfMemoryError or similar"); } catch (OutOfMemoryError e) {