Little bIT awesome

[Stack] 스택 본문

CS 공부/Data Structure

[Stack] 스택

까루카라 2024. 2. 6. 10:00

Stack

스택(Stack)의 사전적 정의는 '쌓다', '더미'이다. 즉, 상자에 물건을 쌓아 올리듯이 데이터를 쌓는 자료 구조라고 할 수 있다. 

그림과 같이 스택은 마지막에 저장한 데이터를 가장 먼저 꺼내게 되는 구조 특징이 있는데,

이러한 자료의 구조를 LIFO(Last In First Out) 구조라고 말한다. 


Stack 사용처

스택은 수식계산, 수식 괄호 검사, undo / redo, 웹브라우저의 뒤로 / 앞으로 등에 사용된다. 

 

JVM(자바 가상 머신)의 Runtime Data Area에 Stack 메모리에도 사용된다. 

Stack은 마지막으로 사용이 끝난 지역변수를 바로바로 쳐내버려 메모리를 매우 효율적으로 사용하는 방법이기 때문에

스택의 구조 개념이 프로그래밍 메모리 영역에 고대로 사용되는 것이다. 


자바의 Stack

자바의 Stack 클래스는 Vector 클래스를 상속(extends) 받기 때문에 Thread-Safe 하다는 특징을 가진다. 

 

Thread Safe?

멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가
여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없는 것. 

하나의 함수가 한 스레드로부터 호출되어 실행 중일 때,
다른 스레드가 그 함수를 호출하여 동시에 함께 실행되더라도
각 스레드에서의 함수의 수행 결과가 옳바르게 나오는 것

https://developer-ellen.tistory.com/205

 

스레드 안전(Thread-Safety)란?

멀티 스레드 프로그래밍 멀티스레드 프로그래밍은 하나의 프로세스에서 여러 개의 스레드를 만들어 자원의 생성과 관리의 중복을 최소화하는 것이다. 장점 멀티 프로세스에 비해 메모리 자원

developer-ellen.tistory.com

 


Stack 사용법

자바는 java.util.Stack 클래스를 통해 Stack 동작을 제공하고 있다. 

일반적으로 스택에 데이터를 추가하는 동작은 push라고 하며, 스택에서 데이터를 빼는 동작은 pop이라고 한다. 

 

import java.util.Stack;

 

메서드 설 명
boolean empty() Stack이 비어있는지 알려준다. 
Object peek() Stach의 맨 위에 저장된 객체를 반환
pop과 달리 Stack에서 객체를 꺼내지는 않는다. 
비어있을 경우 EmptyStackException 발생
Object pop() Stack의 맨 위에 저장된 객체를 꺼낸다. 
비어있을 경우 EmptyStackException 발생
Object push(Object item) Stack에 객체(item)을 저장한다. 
int search(Object o) Stack에서 주어진 객체(o)를 찾아서 그 위치를 반환
못 찾을 경우 -1을 반환
배열과 달리 위치는 0이 아닌 1부터 시작

 


Stack에 요소 넣기

Stack<Integer> stack = new Stack<>();

stack.push(1);
stack.push(2);
stack.push(3);

System.out.println(stack);

 


Stack에 요소 꺼내기

Stack은 나중에 넣은 것이 먼저 나오는 LIFO(Last In Firsh Out) 구조이기 때문에

넣은 순서와 반대로 꺼내지게 된다. 

 

System.out.println(stack.pop()); // 3

System.out.println(stack); // [1, 2]

System.out.println(stack.pop()); // 2
System.out.println(stack.pop()); // 1

System.out.println(stack); // []


Stack 클래스 사용 지양

만일 어플리케이션에 스택 자료 구조를 사용해야 할 상황일 때, 자바의 스택 클래스는 사용을 지양해야 한다. 

그 이유는, Stack 자료 구조가 Vector 컬렉션을 상속받아 구현되었기 때문인데, 

이 Vector 클래스 자체가 컬렉션 프레임워크라는 개념이 나오기 전 자바1에서부터 있었던 굉장히 오래된 클래스이기 때문에

취약점이 많고 부적합한 부모 클래스의 메소드가 상속되어 자식 클래스 인스턴스의 상태가 불안정해질 수 있다. 

 

예를 들어 부모 클래스의 add 메소드가 외부로 노출되어 의도치 않은 동작이 실행될 수 있다. 

Stack<String> stack = new Stack<>();
stack.push("one");
stack.push("two");
stack.push("three");

stack.add(0, "four"); // add 메소드를 호출함으로써 stack의 의미와는 다르게 특정 인덱스의 값이 추가

// 마지막에 넣은 요소는 "four" 인데 스택은 "three"로 뽑혀진다
String str = stack.pop(); // three
System.out.println(str.equals("four")); // false

 


Stack 대신 Deque  사용할 것

자바 공식 문서에도 Stack 클래스보다 Deque 클래스를 사용하여 구현할 것을 권장하고 있다.

 

 

참고자료

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

 

🧱 자바 Stack 구조 & 사용법 정리

Stack 컬렉션 스택(Stack)의 사전적 정의는 '쌓다', '더미' 로서 접시 스택처럼 접시를 쌓아놓은 것을 말한다. 즉, 상자에 물건을 쌓아 올리듯이 데이터를 쌓는 자료 구조라고 할 수 있다. 아래 그림

inpa.tistory.com