데이터의 묶음을 저장하고, 사용하는 방법을 정의한 것
대부분의 자료 구조는 특정한 상황에 놓인 문제를 해결하는 데에 특화되어 있다. 따라서 많은 자료 구조를 알아두면, 어떠한 상황이 닥쳤을 때 적합한 자료 구조를 빠르고 정확하게 적용하여 문제를 해결할 수 있다.
Stack은 쌓다
, 쌓이다
, 포개지다
와 같은 뜻을 가지고 있다.
예1) 1, 2, 3, 4를 스택에 차례대로 넣습니다.
Stack<Integer> stack = new Stack<>(); //Integer형 스택 선언
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
---------------------------
1 <- 2 <- 3 <- 4
---------------------------
들어간 순서대로, 1번이 제일 먼저 들어가고 4번이 마지막으로 들어가게 됩니다.
예2) 스택이 빌 때까지 데이터를 전부 빼냅니다.
stack.pop();
stack.pop();
stack.pop();
stack.pop();
---------------------------
4, 3, 2, 1
---------------------------
제일 마지막에 있는 데이터부터 차례대로 나오게 됩니다.
예3) 스택이 비어 있는지 확인할 때는 empty 연산을 사용합니다.
stack.empty(); // true 반환
1. Stack클래스는 Vector클래스를 상속받아 구현되어 있다. 따라서 크기를 동적으로 조정하지 않는다.
- Vector클래스는 내부적으로 배열을 사용하여 구현되어 있다.
- 지정된 크기만큼 배열이 할당된 후, 데이터의 개수가 배열의 크기를 초과하면 새로운 배열을 할당한다.
- 이후, 기존 데이터를 새로운 배열로 복사하는 작업을 수행한다.
- 따라서 크기가 자주 변하는 스택에서는 다른 자료 구조를 사용하는 것이 더 효율적이다.
Vector 클래스의 생성자 코드
public Vector(Collection<? extends E> c) {
Object[] a = c.toArray();
elementCount = a.length;
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, elementCount, Object[].class);
}
}
2. Java에서 제공하는 Stack클래스는 Vector클래스를 상속받아 구현되어 있어, 중간에서 데이터를 삽입, 삭제가 가능하다.
- Vector클래스의 모든 메서드를 상속받기에 당연히 Stack클래스는 상속받은 메서드 중 일부를 오버라이딩하여 구현이 가능하다.
- 스택의 의도된 동작을 방해할 수 있기 때문에 주의가 필요하다.
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
stack.get(1); // 특정 인덱스 원소 찾기
stack.set(1, 1); // 특정 인덱스에 원소 넣기
stack.remove(1); // 특정 인덱스 원소를 삭제
주로사용되는 곳, 브라우저에서 뒤로 가기, 앞으로 가기 버튼을 사용할 때.
Queue는 줄을 서서 기다리다
라는 뜻을 가지고 있다.
예1) 1, 2, 3, 4를 큐에 차례대로 넣습니다.
Queue<Integer> queue = new LinkedList<>(); //int형 queue 선언
queue.add(1); // queue에 값 1 추가
queue.add(2); // queue에 값 2 추가
queue.add(3); // queue에 값 3 추가
queue.add(4); // queue에 값 4 추가
queue.add(데이터)
출력 방향 <---------------------------< 입력 방향
1 <- 2 <- 3 <- 4
<---------------------------<
들어간 순서대로, 1번이 제일 먼저 들어가고 4번이 마지막으로 들어가게 됩니다.
예2) 큐가 빌 때까지 데이터를 전부 빼냅니다.
queue.poll(); // queue에 첫번째 값을 반환하고 제거
queue.poll();
queue.poll();
queue.poll();
queue.poll()
출력 방향 <---------------------------< 입력 방향
<---------------------------<
1, 2, 3, 4
제일 첫 번째 있는 데이터부터 차례대로 나오게 됩니다.
3.1 queue.offer()
Queue<Integer> queue = new LinkedList<>();
boolean result = queue.offer(1); // 실패하면 false 반환
3.2 add()
Queue<Integer> queue = new LinkedList<>();
queue.add(1); // IllegalStateException 발생 가능
3.3 poll()
queue.poll(); // 큐에서 가장 처음에 들어온 데이터를 제거
보통은 큐에 요소를 추가할 때 offer() 메서드를 사용하는 편이 좋다. add() 메서드는 예외를 발생시키므로, 예외 처리를 위한 추가적인 코드를 작성해야 합니다. offer() 메서드는 예외 없이 실패 시에도 처리가 가능하므로 더 유연하게 사용할 수 있다.