Stack 대신 Deque를 사용하는 이유 #16
Replies: 6 comments
자바의 자료구조에서 Stack 대신 Deque를 사용하는 이유를 설명하세요.자바 공식 문서에서는 Stack 클래스에 대해서, Stack 클래스를 사용하기 보다는 Deque 인터페이스와 그 구현체를 사용하라고 말한다. Queue는 FIFO(선입선출)의 특징을 가지고 있는 자료구조이다. 자바에서는 Queue는 보통 구현체로 LinkedList를 사용한다. Stack은 LIFO(후입선출)의 특징을 가지고 있는 자료구조이다. 자바에서는 Stack은 그 자체로 구현체이므로 다음과 같이 사용한다. Deque는 Double Ended Queue의 약자로, 흔히 양방향 큐라고 불리는 것이다. 자바에서는 Stack 클래스는 앞서 말했듯이 Vector 클래스를 상속하여 구현되어 있다. Vector 클래스는 List를 구현한 클래스로 자바 1.0부터 제공되어 왔다. 하지만 성능 상의 문제로 사용이 권장되지 않고 있다. 결과적으로 Stack 클래스도 사용이 권장되지 않게 된 것이다. Stack과 ArrayDeque의 관계는 Vector와 ArrayList의 관계와 매우 유사하다. 다시 말해 Stack을 사용하면 안되는 이유는 Vector를 사용하면 안되는 이유와 동일하다고 볼 수 있다. 이러한 문제는 외부 동기화를 통해 해결할 수 있다. 위 예시와 같이 동기화 처리를 외부에서 해주면 Deque를 멀티 쓰레드 환경에서도 안전하게 사용할 수 있다. 요약
|
자바의 자료구조에서 Stack 대신 Deque를 사용하는 이유를 설명하세요.stack클래스는 오래된 클래스로 설계되어 성능과 설계 측면에서 비효율적이라고 한다. stack은 vector클래스를 상속받아 모든 메서드가 동기화 되어 있다. 혼자 프로그램을 사용하는 단일 스레드 환경에서까지 동기화가 일어나면 불필요한 성능 저하가 발생할 수 있기 때문에 보통 deque를 사용한다. ArrayDeque는 스택과 큐 기능을 모두 지원하며, stack처럼 불필요환 동기화를 하지 않기 때문에 성능이 더 우수하다. |
자바의 자료구조에서 Stack 대신 Deque를 사용하는 이유를 설명하세요.Stack과 Deque의 큰 차이점은 출입구의 개수이다. Stack은 접시를 위에 쌓아 사용하는 탑으로 표현한다면, Deque는 양쪽이 모두 뚫린 종이박스와 같다. 이것만 봐도 Deque가 Stack에 비해 제약이 적고 활용도, 속도 측면에서 더 효율적인 자료구조라고 판단 가능하다. 앞에서 넣고 앞에서 빼면 스택처럼, 앞에서 넣고 뒤에서 빼면 큐처럼 Deque로 구현 가능하다. 코드예시) import java.util.ArrayDeque;
import java.util.Deque;
public class Main {
public static void main(String[] args) {
//Stack<Integer> stack = new Stack<>(); 대신 아래 사용
Deque<Integer> stack = new ArrayDeque<>();
stack.push(10);
stack.push(20);
stack.push(30);
System.out.println(stack.pop()); // 30
System.out.println(stack.pop()); // 20
System.out.println(stack.pop()); // 10
}
}참고) Q. Deque와 ArrayDeque의 차이점은?
Q. ArrayDeque가 배열 기반이라 빠르다했는데, 배열은 addFirst동작같이 추가,삭제 작업에서 비효율적인 자료구조 아닌가?
또다른 이유Stack은 Vector를 상속받고 있어, Stack의 주원칙인 LIFO에 맞지 않는 메서드를 지원할 가능성이 있다. 또한 Vector는 멀티스레드 환경여부와 상관없이 성능저하를 일으킨다. 그래서 SonarLint와 자바 공식문서에서는 stack 대신 deque을 사용하는 것을 추천한다. 아래 사진과 같이 Deque는 Queue를 상속받으며, Queue는 Collection을 상속받기에 더욱 안정적인 LIFO 형태의 기능을 제공할 수 있다.
다음에 추가 공부)
-> |
정리 자바에서 옛날에 Stack 을 만들긴 만들었는데, 막상 만들고 보니 허점이 많음. → Deque를 쓰자 |
자바의 자료구조에서 Stack 대신 Deque를 사용하는 이유를 설명하세요.
vector 를 상속받은게 문제가 됨. 우선 상속은 isA 관계가 성립할 때 사용하는 객체지향 프로그래밍 기법이다. 근데 엄격한 LIFO 가 지켜져야 하는 stack 은 일반 리스트와는 다른 개념을 가지고 있다. stack 클래스 설계 시, 잘못된 설계방법으로 인해 isA 관계가 아님에도 불구하고 상속으로 구현된 것이다. 그래서 부모인 vector 클래스가 가지고 있는 public 메서드 add, remove 같은 LIFO를 지키지 않는 메서드가 stack 에서 사용가능한 상태가 된다. 따라서 vector 상속이 java 에서 stack 을 사용하지 않는 원인 중 하나가 된다. 또한, vector 의 대부분의 메서드는 synchronized 가 붙어있어서, 동기방식으로만 작동하기 때문에 메서드 단위로 락을 건다. os에서 아사현상과 유사하게, 락을 걸어도, 아사현상이 발생할 수 있기 때문에 외부에서 동기처리를 해주어야 하고, 비동기 환경(멀티스레드) 가 아니더라도 락을 열고 거는 오버헤드가 발생하기 때문에 비효율적인 클래스가 되었다. |
1. 자바의 자료구조에서 Stack 대신 Deque를 사용하는 이유를 설명하세요.먼저 Stack은 후입선출로 마지막에 들어간 데이터가 가장 먼저 나오는 자료구조이고 Deque은 양방향 자료구조로 어디로든 삽입 삭제가 가능한 자료구조입니다. 그런데 Stack 대신 Deque를 사용하는 이유는 Stack은 Vector를 상속받은 자료구조입니다. 객체지향 설계로 보면 상속 관계는 is-A 관계를 가져야 하지만 Stack은 한쪽에서만 조작해야하는 자료구조이지만 Vector가 가진 다른 리스트 조작 매서드도 갖게 되고 이런 점이 Stack의 후입선출의 구조를 깨트리게 됩니다. 그리고 또 Vector와 이를 상속 받은 Stack은 주요 매서드에 synchronized 키워드가 붙어 있기 때문에 단일 스레드 환경에서도 락, 해제의 오버헤드가 존재해 성능적인 부분에서도 뒤쳐집니다. 이렇게 Stack의 객체지향 설계의 오류, 비효율적인 성능의 이유로 Deque를 사용하고 이를 자바 공식 문서에서도 권고됩니다. |

Uh oh!
There was an error while loading. Please reload this page.
📆 일자: 26년 7월 21일(화)
오늘의 질문
자바의 자료구조에서 Stack 대신 Deque를 사용하는 이유를 설명하세요.
All reactions