1. 스택에 대한 기본 지식


스택의 사전적 정의 : 쌓다.
위 사진 처럼 한쪽 입구가 막힌 구조에서 원하는 데이터를 다루는 자료구조이다.
하나의 컵이라고 생각하면 이해가 빠를 것 같다.

LIFO

즉, last in first out이다.
선입 선출의 큐와는 다르게 먼저 들어간 것이 가장 나중에 나오는 구조이다.

2. 자바에서의 스택 사용방법

먼저 자바에서 스택을 사용하려면, 다음 클래스를 import하면 된다.

import java.util.Stack;

2.1 스택 클래스의 매서드

1. empty()

해당 스택이 비어있는지 확인하며,
반환 값은 true & false이다.

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        System.out.println("스택 비어 있는가? " + stack.empty()); // true

        stack.push(10);
        System.out.println("스택 비어 있는가? " + stack.empty()); // false
    }
}

2. peek()

스택 최상단의 요소를 반환하지만, 제거하지는 않는다.

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(20);
        stack.push(30);

        System.out.println("스택 최상단 요소: " + stack.peek()); // 30
        System.out.println("스택 상태: " + stack); // [20, 30]
    }
}

예외!!!
만약 스택이 비어있으면 EmptyStackException 발생.
비어있는 상태에서는 무언가를 꺼낸다는 것은 논리적으로 불가능하기 때문이다.

3. pop()

스택의 최상단에 있는 요소를 반환하고, 해당 요소를 스택에서 제거한다.

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(40);
        stack.push(50);

        System.out.println("스택에서 제거된 요소: " + stack.pop()); // 50
        System.out.println("스택 상태: " + stack); // [40]
    }
}

위의 peek()와 동일한 상황에서 예외가 발생한다.
역시 같은 이유이다.

4. push(Object item)

스택의 최상단에 요소를 추가

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();
        stack.push("A");
        stack.push("B");

        System.out.println("스택 상태: " + stack); // [A, B]
    }
}

5. search(Object o)

스택에서 지정된 객체의 1-based index를 반환.
만약 원하는 값이 없으면 -1을 반환한다.

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();
        stack.push("A");
        stack.push("B");
        stack.push("C");

        System.out.println("B의 위치: " + stack.search("B")); // 2
        System.out.println("Z의 위치: " + stack.search("Z")); // -1
    }
}

3. 하지만 권장되지 않는 Stack의 사용?

위에서 스택에 대해 주구장창 알아보았다.
하지만 동시에 우리는 스택 클래스를 사용하면 안된다.
정확히 말하면 Deprecated되었다.

Vector 클래스를 상속받은 스택 클래스는 아주 오래전부터 만들어진 클래스이고,
그만큼 수많은 문제점들이 발생되었다.

따라서, 자바의 공식 문서에는 애당초 상속을 잘못하여 설계된 Stack클래스보다 Deque클래스를 사용할 것을 지향한다.

덱의 구조는 다음과 같다.

이것을 가지고 스택으로 활용하면 되는 것이다.

덱 사용이 권장 되는 이유(장점)

  1. 가벼움:
    ArrayDeque는 스택과 큐 양쪽에 적합하며, Vector 기반의 Stack보다 메모리 오버헤드가 적습니다.
  2. 쓰레드 안전성:
    Stack은 동기화되어 있어 성능이 낮을 수 있습니다. Deque는 기본적으로 동기화되지 않아 단일 스레드 환경에서 빠릅니다.
  3. 유연성:
    Deque는 큐와 스택 모두로 사용할 수 있는 유연한 자료구조입니다.

실제 코드를 보면 다음과 같다.

/* Deque를 Stack 처럼 사용하기 */
Deque<String> stack = new ArrayDeque<>();

stack.push("a");
stack.push("b");
stack.push("c");
stack.push("d");
stack.push("e");

System.out.println(stack); // [a, b, c, d, e]

System.out.println(stack.pop()); // e
System.out.println(stack.pop()); // d

System.out.println(stack); // [a, b, c]

출처

https://inpa.tistory.com/entry/JCF-%F0%9F%A7%B1-Stack-%EA%B5%AC%EC%A1%B0-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC

profile
내가 있는 그 조직에서 가장 성실하기만 하자

0개의 댓글