본문 바로가기

Java/기본

[Java] 컬렉션프레임워크103 - List 컬렉션 - Stack, queue

Stack, queque

stack 과 queue(발음 : 큐)는 각각 후입선출과 선입선출을 대표하는 자료구조이다.


Stack

Vector 클래스를 상속받는 하위클래스이다. 후입선출(LIFO, last-in-first-out) 구조를 가진 데이터 구조이다. 즉 가장 마지막에 넣은 것이 가장 상위(우선순위)에 있게 되는 클래스이다. 사실 Stack 은 많이 사용되는 클래스는 아니지만, 마지막에요청받은 데이터를 바로 확인하려는 경우 등 특별한 목적을 위해 사용되기도 한다.

 

Stack 상속구조

Stack 상속구조

 

* 후입선출 예시 *
현금통 : 가장 마지막에 넣은 천원짜리 지폐가 가장 위에 있게 되며, 꺼낼때는 위에 있는것부터 가져오게 된다

 

Stack 주요 메서드

메서드 내용
boolean empty() 비어있는지 여부
E peek() (삭제없이) 스택의 상단에 위치한 객체 가져오기
E pop() (삭제하면서) 스택의 상단에 위치한 객체 가져오기
E push(E item) 스택 상단에 올려놓기
int search(Object o) 스택의 상단에서 몇번째에 있는지 세기
(최상단이 1번째, 밑으로 내려갈수록 숫자 커짐)

 

코드 예제

import java.util.Stack;

public class StackEx {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();
        
        //Stack에 객체 추가하기
        stack.push("달팽이");
        stack.push("나비");
        stack.push("고양이");
        stack.push("하마");
        stack.push("코끼리");

        //.peek() -> 삭제하지 않고 최상단의 값 가져오기
        System.out.println(stack.peek());   //코끼리
        System.out.println(stack.peek());   //코끼리
        System.out.println(stack.peek());   //코끼리

        System.out.println(stack.pop());   //코끼리
        System.out.println(stack.pop());   //하마
        System.out.println(stack.pop());   //고양이
        System.out.println(stack.pop());   //나비
        System.out.println(stack.pop());   //달팽이

        System.out.println(stack.empty());  //true

        //다시 값 추가
        stack.push("토끼");
        stack.push("여우");
        stack.push("하이에나");
        stack.push("치타");

        int count = stack.search("하이에나");
        System.out.println(count);  //2 -> 위에서 2번째 위치해있다
    }

 


queue

LinkedList 등을 구현클래스로 가지는 인터페이스이다. 선입선출(FIFO, first-in-first-out) 구조를 가진다. 즉 먼저 넣은 것이 가장 우선순위에 있게 되는 구조를 가진다. Stack 클래스와 반대로 Queue인터페이스는 자주 사용된다. 특히 사용자 요청을 순서대로 처리하는 것이 중요한 경우에 활용될 수 있다. 예를들어 음식 조리순서, 은행 대기고객 처리순서 등 요청에 대한 처리순서가 중요한 경우에 활용된다.

* 선입선출 예시 *
수도관 : 수도관을 통과하는 물은 먼저 들어간 순서에 따라 수도꼭지로 나오게 된다.

 

Queue 상속구조

Queue의 상속구조

 

Stack 클래스와 반대로 Queue인터페이스는 자주 사용된다. 특히 사용자 요청을 순서대로 처리하는 것이 중요한 경우에 활용될 수 있다. 예를들어 음식 조리순서, 은행 대기고객 처리순서 등 요청에 대한 처리순서가 중요한 경우에 활용된다.

Queue인터페이스의 상속구조를 보면 구현클래스 중에 LinkedList가 있는 것을 확인할 수가 있다. '어? LinkedList는 List인터페이스를 구현했는데..?' 라는 생각이 들었다면 잘 기억한 것이다. LinkedList는 List인터페이스와 Queue인터페이스를 모두 구현하는, 즉 2가지 인터페이스의 특성을 모두 가지는 구현체라고 할 수 있다.

 

 

Queue 주요 메서드

메서드 내용
boolean add(E e) 큐에 객체 추가하기. 추가할 공간 없으면 IllegalStateException 예외 발생
E element() (삭제없이) 가장 앞에 있는 객체 반환
boolean offer(E e) 큐에 객체 추가하기. 추가할 공간 없으면 false 리턴
E peek() (삭제없이) 가장 앞에 있는 객체 반환
E poll() (삭제하면서) 가장 앞에 있는 객체 반환
E remove() (삭제하면서) 가장 앞에 있는 객체 반환

 

 

코드 예제

import java.util.LinkedList;
import java.util.Queue;

public class QueueEx {
    public static void main(String[] args) {
        Queue foods = new LinkedList();

        foods.add("된장찌개");
        foods.add("콩나물국밥");
        foods.add("청국장");
        foods.add("김치찌개");
        foods.add("불고기");

        //가장 앞에 있는 값 가져오기
        //.element() 는 리턴타입이 Object이기 때문에 다운캐스팅 해준다
        String foodFirst = (String) foods.element();
        System.out.println(foodFirst);

        String food01 = (String) foods.peek();
        String food02 = (String) foods.peek();
        String food03 = (String) foods.peek();

        //.peek() 은 삭제하지 않고 가장 앞에 있는 값을 가져온다
        System.out.println(food01);
        System.out.println(food02);
        System.out.println(food03);

        //.poll()은 삭제하면서 가장 앞에 있는 값을 가져온다
        String food11 = (String) foods.poll();
        String food12 = (String) foods.poll();
        String food13 = (String) foods.poll();
        String food14 = (String) foods.poll();
        String food15 = (String) foods.poll();

        System.out.println(food11);
        System.out.println(food12);
        System.out.println(food13);
        System.out.println(food14);
        System.out.println(food15);
    }
}