Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

자바 스택(Stack) 클래스 완벽 가이드: LIFO 구조와 핵심 메서드 활용법

자바에서 스택(Stack)은 후입선출(LIFO, Last-In First-Out) 방식으로 동작하는 자료구조입니다. 즉, 스택에서 가장 먼저 제거되는 요소는 가장 마지막에 추가된 요소입니다. 새로운 요소는 항상 스택의 끝(꼭대기)에 추가되며, 자바의 Stack 클래스는 Vector 클래스를 확장하여 만들어졌습니다.

프로그래밍에서 스택은 데이터를 저장하기 위해 사용되는 후입선출(LIFO) 자료구조입니다. 스택은 다양한 상황에서 유용하게 활용됩니다. 예를 들어, 리스트의 대칭 여부를 검사하거나 리스트의 순서를 뒤집을 때 스택을 사용할 수 있습니다.

자바 컬렉션 프레임워크에는 스택을 구현할 수 있는 Stack 클래스가 포함되어 있습니다. 이 글에서는 자바 스택의 기본 개념, 스택 생성 방법, 그리고 Stack 클래스가 제공하는 주요 메서드들을 예제 코드와 함께 살펴보겠습니다.

자바 스택이란?

자바 스택은 요소를 후입선출(LIFO) 구조로 저장합니다. 다시 말해, 스택의 맨 위에 추가된 요소가 가장 먼저 제거됩니다.

스택이 실제로 활용되는 대표적인 예는 웹 브라우저의 페이지 이동 기능입니다. 웹 페이지에 접속하면 브라우저는 해당 페이지를 방문 기록에 추가합니다. 이 방문 기록이 바로 스택입니다.

브라우징 세션 동안 새로운 웹 페이지에 방문할 때마다 브라우저는 방문 스택에 새 항목을 추가합니다. 직전에 방문한 페이지로 돌아가고 싶으면(후입), 브라우저는 스택에서 가장 최근 항목을 먼저 제거합니다(선출). 아래 표는 스택의 예시를 보여줍니다.

사이트 이름
google.com
nytimes.com
careerkarma.com

위 표는 브라우징 히스토리 스택입니다. 현재 google.com 메인 페이지에 접속해 있는 상태이며, 그 전에는 뉴욕타임스 메인 페이지, 그보다 전에는 Career Karma 메인 페이지에 있었습니다.

google.com은 스택의 맨 위에 위치하며, 브라우저가 스택에서 가장 먼저 제거하는 항목입니다. 뒤로 가기 버튼을 눌러 이전 페이지로 돌아갈 때 바로 이 과정이 일어납니다.

또 다른 예로 책 더미를 들 수 있습니다. 책 더미를 살펴보려면 맨 위의 책부터 아래 순서대로 확인해야 합니다. 마지막에 쌓은 책을 가장 먼저 보게 되는 것이죠. 이것이 바로 LIFO 구조입니다.

스택을 다룰 때는 목록에서 가장 마지막에 위치한 항목을 스택의 꼭대기(top)라고 간주합니다. 앞선 웹사이트 예시에서 google.com이 가장 최근에 방문한 사이트였기 때문에 스택의 맨 위에 있는 것입니다.

자바 스택 생성하기

자바에서 스택을 생성하기 전에 먼저 java.util.Stack 패키지를 임포트해야 합니다. 이 패키지에는 이 글에서 사용할 스택 자료구조가 포함되어 있습니다.

스택 자료구조를 임포트하는 방법은 다음과 같습니다.

import java.util.Stack;

패키지를 임포트했다면 이제 자바 스택을 생성할 수 있습니다. 자바에서 스택을 생성하는 문법은 다음과 같습니다.

Stack<DataType> stack_name = new Stack<>();

각 구성 요소의 의미는 다음과 같습니다.

  • Stack: 스택을 선언하겠다고 프로그램에 알리는 부분입니다.
  • DataType: 스택에 저장할 데이터의 타입입니다.
  • stack_name: 생성할 스택의 이름입니다.
  • new Stack<>();: 새로운 자바 스택 객체를 초기화합니다.

예를 들어 문자열을 저장하는 books라는 이름의 스택을 만들고 싶다면 다음 코드를 사용할 수 있습니다.

Stack<String> books = new Stack<>();

이렇게 하면 후입선출 방식으로 데이터를 저장하는 새로운 스택이 완성됩니다.

참고: Deque 클래스

일부 개발자들은 자바에서 Stack 클래스 대신 Deque 클래스를 사용하는 것을 선호한다는 점도 알아두면 좋습니다.

Deque(Double-Ended Queue)는 양방향 큐입니다. Deque가 스택보다 갖는 장점은 큐의 양쪽 끝에서 모두 요소를 추가하고 제거할 수 있다는 것입니다. 반면 스택에서는 이것이 불가능합니다.

만약 스택 전용 메서드(아래에서 설명)를 사용한다면 코드에서 Stack 클래스를 계속 사용해야 하는데, 이는 프로그램 확장 시 유연성을 떨어뜨릴 수 있습니다. 그럼에도 불구하고 Stack 클래스는 자바에서 여전히 폭넓게 활용되고 있습니다.

자바 스택의 주요 메서드

자바의 Stack 클래스는 스택에 저장된 데이터를 조작할 수 있는 다양한 메서드를 제공합니다. 이 메서드들은 다음 두 가지 범주로 나눌 수 있습니다.

  1. Vector 클래스로부터 상속받은 메서드: Stack 클래스가 제공하는 첫 번째 메서드 그룹은 Vector 클래스에서 상속받은 것들입니다. 이에 대해 더 알고 싶다면 '자바 Vector 클래스' 관련 자료를 찾아보시기 바랍니다.
  1. Stack 고유의 메서드: Stack 클래스는 자체적으로 5개의 고유 메서드를 추가로 제공합니다. 각 메서드는 다음과 같습니다.
  • push()
  • pop()
  • peek()
  • empty()
  • search()

그중 push()와 pop()이 가장 많이 사용되는 연산입니다. 각각 스택에 요소를 추가하고 제거하는 역할을 담당합니다.

스택에 요소 추가하기: push()

push() 메서드는 자바 스택에 요소를 추가합니다.

push()는 하나의 매개변수, 즉 스택에 추가할 항목을 받습니다. 예를 들어 도서관 소설 코너의 모든 책 제목을 저장하는 스택을 만든다고 가정해 봅시다. 다음 코드로 처음 세 권의 책 제목을 스택에 추가할 수 있습니다.

import java.util.Stack;

class AddBooks {
	public static void main(String[] args) {
		Stack<String> books = new Stack<>();

		books.push("Pride and Prejudice");
		books.push("Nineteen Eighty-Four");
		books.push("The Great Gatsby");

		System.out.println(books);
	}
}

실행 결과는 다음과 같습니다.

[Pride and Prejudice, Nineteen Eighty-Four, The Great Gatsby]

먼저 자바 스택 모듈을 임포트하고, 프로그램 코드를 담을 AddBooks라는 클래스를 선언합니다.

다음 줄에서는 문자열 값을 저장할 수 있는 books라는 새로운 스택을 초기화합니다. 그런 다음 push() 메서드를 사용해 Pride and Prejudice, Nineteen Eighty-Four, The Great Gatsby 세 권의 책 제목을 스택에 차례로 추가합니다. 마지막으로 books 스택에 저장된 책 제목들을 콘솔에 출력합니다.

스택에서 요소 제거하기: pop()

pop() 메서드는 스택 맨 위의 요소를 제거합니다. 이 메서드는 스택에서 제거된 요소를 반환합니다.

앞서 입력한 마지막 책 제목인 The Great Gatsby를 스택에서 제거하고 싶다고 가정해 봅시다. 위 프로그램에 다음 코드를 추가하면 됩니다.

class RemoveBooks {
	public static void main(String[] args) {
		Stack<String> books = new Stack<>();

		books.push("Pride and Prejudice");
		books.push("Nineteen Eighty-Four");
		books.push("The Great Gatsby");

		String removed_book = books.pop();
		System.out.println("Books: " + books);
		System.out.println("Removed book: " + removed_book);
	}
}

실행 결과는 다음과 같습니다.

Books: [Pride and Prejudice, Nineteen Eighty-Four]
Removed book: The Great Gatsby

이 예제에서 코드는 스택 맨 위에 있는 항목을 제거합니다. 스택의 맨 위 항목은 The Great Gatsby입니다. 그런 다음 프로그램은 수정된 책 목록을 Books:라는 접두사와 함께 콘솔에 출력하고, 제거된 책의 제목 역시 Removed book:이라는 접두사와 함께 화면에 표시됩니다.

스택의 맨 위 요소 조회하기: peek()

스택을 다루다 보면 맨 위에 어떤 항목이 있는지 확인만 하고 싶을 때가 있습니다. 이때 사용하는 것이 peek() 메서드입니다. peek()는 매개변수를 받지 않으며, 스택의 맨 위를 '훔쳐보고' 해당 항목을 반환합니다.

The Great Gatsby를 제거한 후, 현재 스택의 맨 위에 어떤 항목이 있는지 알고 싶다고 가정해 봅시다. 다음 코드를 사용하면 됩니다.

import java.util.Stack;

class FindTopBook {
	public static void main(String[] args) {
		Stack<String> books = new Stack<>();

		books.push("Pride and Prejudice");
		books.push("Nineteen Eighty-Four");

		String top_book = books.peek();

		System.out.println("Book at top of stack: " + top_book);
	}
}

실행 결과는 다음과 같습니다.

Book at top of stack: Nineteen Eighty-Four.

현재 스택에는 두 개의 항목이 있으며, Nineteen Eighty-Four가 스택의 맨 위에 있습니다. 따라서 peek() 메서드를 호출하면 해당 책 제목이 반환됩니다.

스택이 비었는지 확인하기: empty()

empty() 메서드는 스택이 비어 있는지 여부를 판단합니다.

예를 들어, books 스택이 비어 있는지 확인하고 싶다고 가정해 봅시다. 스택의 데이터를 여러 차례 조작한 후에는 스택에 더 이상 책 제목이 남아 있는지 확실하지 않을 수 있습니다.

다음 코드로 스택이 비어 있는지 확인할 수 있습니다.

import java.util.Stack;

class CheckBooksEmpty {
	public static void main(String[] args) {
		Stack<String> books = new Stack<>();

		books.push("Pride and Prejudice");
		books.push("Nineteen Eighty-Four");

		boolean is_empty = books.empty();

		System.out.println("Is the book stack empty? " + is_empty);
	}
}

실행 결과는 다음과 같습니다.

Is the book stack empty? false

books 스택에는 두 개의 값이 남아 있으므로 비어 있지 않습니다. 따라서 books.empty()는 false를 반환합니다.

요소 검색하기: search()

search() 메서드는 스택에서 특정 요소를 검색합니다.

search()는 하나의 매개변수, 즉 찾으려는 항목의 이름을 받으며, 해당 항목이 스택에서 차지하는 위치를 반환합니다. 이때 위치는 스택의 맨 위를 기준으로 1부터 시작하여 계산됩니다.

책 제목 스택에서 Pride and Prejudice의 위치를 알고 싶다고 가정해 봅시다. 다음 코드를 사용하면 됩니다.

import java.util.Stack;

class FindPrideBookPosition {
	public static void main(String[] args) {
		Stack<String> books = new Stack<>();

		books.push("Pride and Prejudice");
		books.push("Nineteen Eighty-Four");

		int find_book = books.search("Pride and Prejudice");

		System.out.println("Position of 'Pride and Prejudice': " + find_book);
	}
}

실행 결과는 다음과 같습니다.

Position of 'Pride and Prejudice': 2

search()는 맨 위 항목을 위치 1로 계산합니다. 현재 스택의 맨 위는 Nineteen Eighty-Four이므로 위치가 1이고, 그 아래에 있는 Pride and Prejudice는 위치 2를 반환받게 됩니다.

마무리

자바의 Stack 클래스는 LIFO 구조의 스택을 생성할 때 사용됩니다. 이 글에서는 자바 스택의 기본 개념과 스택 생성 방법을 살펴보았고, 스택의 내용을 조회하고 조작하는 데 사용되는 5가지 핵심 메서드(push, pop, peek, empty, search)까지 예제와 함께 정리했습니다.

이제 전문 자바 개발자처럼 스택을 활용할 준비가 되었습니다. 자바 프로그래밍 언어에 대해 더 깊이 배우고 싶다면 'How to Learn Java' 가이드를 참고해 보시기 바랍니다.