자바 - 데이터 구조

안녕하세요, 미래의 프로그래머 여러분! 오늘 우리는 자바 데이터 구조의 흥미로운 세계로 접근해 보겠습니다. 여러분의 친절한 이웃 컴퓨터 과학 교사로서, 저는 이 여정을 단계별로 안내해 드리겠습니다. 프로그래밍 초보자라면 걱정하지 마세요 - 우리는 기본부터 시작하여 차근차근 올라갈 테니까요. 그럼 가상의 안전帽을 쓰고, 지식을 쌓아 나가보겠습니다!

Java - Data Structures

데이터 구조 소개

구체적인 자바 데이터 구조로 뛰어들기 전에, 데이터 구조가 무엇이고 왜 중요한지 이해해 보겠습니다.

가상의 도서관을 정리하는 상상해 봅시다. 모든 책을 한 쌓이에 쌓아둘 것인가요? 물론 그렇지 않죠! 책들을 쉽게 찾고 관리할 수 있도록 정리할 것입니다. 이와 같은 방식으로 데이터 구조는 프로그래밍에서 우리의 데이터를 조직하고 저장합니다.

데이터 구조는 데이터를 효율적으로 접근하고 수정할 수 있도록 조직하고 저장하는 방법입니다. 자바에서는 여러 가지 내장된 데이터 구조를 사용할 수 있으며, 각각의 장점과 사용 사례가 있습니다.

자바 내장 데이터 구조

자바에서 가장 일반적인 데이터 구조 중 몇 가지를 탐구해 보겠습니다.

열거형(Enumeration)

열거형은 하나씩 숫자를 내주는 티켓 기계 같은东西입니다. 이는 자바의 인터페이스로, 컬렉션의 요소를 하나씩 접근할 수 있게 해줍니다.

다음은 간단한 예제입니다:

import java.util.*;

public class EnumerationExample {
public static void main(String args[]) {
Vector<String> dayNames = new Vector<>();
dayNames.add("월요일");
dayNames.add("화요일");
dayNames.add("수요일");

Enumeration<String> days = dayNames.elements();

while (days.hasMoreElements()) {
System.out.println(days.nextElement());
}
}
}

이 예제에서 우리는 Vector를 사용하여 요소들을 추가하고, Enumeration을 사용하여 이 요소들을 반복합니다. hasMoreElements() 메서드는 더 이상 요소가 있는지 확인하고, nextElement()는 다음 요소를 반환합니다.

비트 집합(BitSet)

비트 집합은 각각이 켜짐(1)과 꺼짐(0) 중 하나인 빛의 스위치 행렬 같은东西입니다. 이는 참/거짓 값을 효율적으로 저장해야 할 때 유용합니다.

다음은 예제입니다:

import java.util.BitSet;

public class BitSetExample {
public static void main(String args[]) {
BitSet bits1 = new BitSet(16);
BitSet bits2 = new BitSet(16);

// 비트 설정
for(int i = 0; i < 16; i++) {
if((i % 2) == 0) bits1.set(i);
if((i % 5) != 0) bits2.set(i);
}

System.out.println("bits1의 초기 패턴: " + bits1);
System.out.println("bits2의 초기 패턴: " + bits2);

// 비트 AND 연산
bits2.and(bits1);
System.out.println("bits2 AND bits1: " + bits2);
}
}

이 예제는 비트 집합을 만들고 비트를 설정하며 비트 연산을 수행하는 것을 보여줍니다.

벡터(Vector)

벡터는 필요에 따라 커지거 줄 수 있는 마법의 배열 같은东西입니다. ArrayList과 유사하지만 동기화되어 있어 스레드 안전합니다.

다음은 벡터를 사용하는 방법의 예입니다:

import java.util.*;

public class VectorExample {
public static void main(String args[]) {
Vector<Integer> vec = new Vector<>(3, 2);
System.out.println("초기 크기: " + vec.size());
System.out.println("초기 용량: " + vec.capacity());

vec.addElement(1);
vec.addElement(2);
vec.addElement(3);
vec.addElement(4);
System.out.println("네 개의 추가 후 용량: " + vec.capacity());

vec.addElement(5);
System.out.println("현재 용량: " + vec.capacity());

System.out.println("첫 번째 요소: " + vec.firstElement());
System.out.println("마지막 요소: " + vec.lastElement());
}
}

이 예제는 벡터를 만들고 요소를 추가하며 크기와 용량을 확인하는 방법을 보여줍니다.

스택(Stack)

스택은 접시 쌓기처럼 맨 위에서만 추가하거나 제거할 수 있습니다. 마지막에 추가된 것부터 먼저 나오는 Last-In-First-Out(LIFO) 원칙을 따릅니다.

스택의 동작을 보겠습니다:

import java.util.*;

public class StackExample {
public static void main(String args[]) {
Stack<String> stack = new Stack<>();
stack.push("밑");
stack.push("중간");
stack.push("위");

System.out.println("스택: " + stack);
System.out.println("팝된 요소: " + stack.pop());
System.out.println("팝 후 스택: " + stack);
System.out.println("peak: " + stack.peek());
System.out.println("peek 후 스택: " + stack);
}
}

이 예제는 요소를 스택에 추가하고, 요소를 제거하며 맨 위 요소를 확인하는 방법을 보여줍니다.

사전(Dictionary)

사전은 키-값 데이터 구조를 나타내는 추상 클래스입니다. 실제 사전처럼 각 단어(키)에 대한 정의(값)가 있습니다.

사전은 직접 인스턴스화할 수 없지만, 그 서브 클래스 Hashtable는 일반적으로 사용됩니다:

import java.util.*;

public class DictionaryExample {
public static void main(String args[]) {
Dictionary<String, String> dict = new Hashtable<>();

dict.put("Apple", "과일");
dict.put("Java", "프로그래밍 언어");
dict.put("Computer", "전자 기기");

System.out.println("사전: " + dict);
System.out.println("키 'Java'의 값: " + dict.get("Java"));

System.out.println("키들: ");
for (Enumeration<String> keys = dict.keys(); keys.hasMoreElements();) {
System.out.println(keys.nextElement());
}
}
}

이 예제는 사전(Hashtable를 통해)을 사용하여 키-값 쌍을 저장하고检索하는 방법을 보여줍니다.

해시 테이블(Hashtable)

해시 테이블은 키-값 쌍을 저장하고 빠르게 값을检索할 수 있는 초고속 파일 캐비닛 같은东西입니다.

다음은 해시 테이블을 사용하는 예제입니다:

import java.util.*;

public class HashtableExample {
public static void main(String args[]) {
Hashtable<String, Integer> numbers = new Hashtable<>();
numbers.put("one", 1);
numbers.put("two", 2);
numbers.put("three", 3);

System.out.println("해시 테이블: " + numbers);
System.out.println("'two'의 값: " + numbers.get("two"));
System.out.println("'four'가 키인가요? " + numbers.containsKey("four"));
System.out.println("3이 값인가요? " + numbers.containsValue(3));

numbers.remove("two");
System.out.println("'two'를 제거한 후 해시 테이블: " + numbers);
}
}

이 예제는 키-값 쌍을 해시 테이블에 추가하고, 값을检索하며 키와 값을 확인하고 항목을 제거하는 방법을 보여줍니다.

속성(Properties)

속성은 문자열 키-값 쌍을 저장하는 특별한 종류의 해시 테이블입니다. 이는 일반적으로 구성 설정을 저장하는 데 사용됩니다.

속성의 동작을 보겠습니다:

import java.util.*;

public class PropertiesExample {
public static void main(String args[]) {
Properties capitals = new Properties();
capitals.put("USA", "워싱턴 D.C.");
capitals.put("France", "파리");
capitals.put("Japan", "도쿄");

System.out.println("속성: " + capitals);
System.out.println("프랑스의 수도: " + capitals.getProperty("France"));

// 기본 값을 설정합니다.
System.out.println("스페인의 수도: " + capitals.getProperty("Spain", "찾지 못함"));

capitals.list(System.out);
}
}

이 예제는 속성을 사용하여 문자열 키-값 쌍을 저장하고检索하며 기본 값을 설정하는 방법을 보여줍니다.

결론

축하합니다! 자바 데이터 구조의 첫 걸음을 냈습니다. 각 구조는 고유한 특성과 사용 사례를 가지고 있습니다. 프로그래밍 여정을 계속하면서, 특정 요구에 따라 다른 구조를 사용하게 될 것입니다.

적절한 데이터 구조를 선택하면 프로그램의 효율성에 큰 차이를 만들 수 있습니다. 마치 올바른 도구를 선택하면 작업이 더 쉬워지는 것과 같은 이치입니다!

이 구조들을 연습하고, 자신의 프로젝트에서 사용해 보며, 두려워하지 말고 실험해 보세요. 행복한 코딩을 기원합니다!

Credits: Image by storyset