자바 코딩 자율학습단 14기 마지막 4주차 학습 후기

3주차 객체지향 기초에 이어, 4주차에는 자바의 컬렉션 프레임워크, 입출력 스트림, 람다 표현식 등 핵심 개념들을 학습했습니다. 데이터 관리와 코드 효율을 높이는 이 중요한 내용들을 16일부터 20일까지 공부한 내용을 정리하여 공유합니다.
16일차 : 컬렉션 프레임워크
package ch10;
public class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
public class Main {
public static void main(String[] args) {
Box<String> box = new Box<>(); // String형의 Box 객체 생성
box.setContent("Hello, World!"); // 문자열 저장
String content = box.getContent(); // 형변환 불필요
System.out.println(content);
}
}
16일차 학습은 자바 컬렉션 프레임워크의 근본 개념에 집중했습니다. ‘컬렉션’과 ‘컬렉션 프레임워크’의 차이를 명확히 이해하고, 프레임워크의 전체 구조를 파악했습니다. 또한, 컬렉션이 객체를 다루기 때문에 기본 타입을 객체 형태로 감싸는 ‘래퍼 클래스’의 역할과, 컬렉션에서 타입 안전성을 보장하는 핵심 기술인 ‘제네릭’의 기본 사용법과 중요성을 함께 학습했습니다. 이 시간은 컬렉션 프레임워크를 본격적으로 사용하기 위한 탄탄한 기초를 다지는 과정이었습니다.
17일차 : 컬렉션 프레임워크
package ch10_collections_simplified;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashSet;
import java.util.HashMap;
public class SimplifiedCollectionsDemo {
public static void main(String[] args) {
System.out.println("--- ArrayList 예제 ---");
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
System.out.println("ArrayList: " + arrayList);
System.out.println("인덱스 0 요소: " + arrayList.get(0));
arrayList.remove("Apple");
System.out.println("Apple 삭제 후: " + arrayList);
System.out.println("-----------------------\n");
System.out.println("--- LinkedList 예제 ---");
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("Cherry");
linkedList.addFirst("Durian");
System.out.println("LinkedList: " + linkedList);
System.out.println("첫 번째 요소: " + linkedList.getFirst());
linkedList.removeLast();
System.out.println("마지막 요소 삭제 후: " + linkedList);
System.out.println("-----------------------\n");
System.out.println("--- HashSet 예제 ---");
HashSet<String> hashSet = new HashSet<>();
hashSet.add("Dog");
hashSet.add("Cat");
hashSet.add("Dog");
System.out.println("HashSet: " + hashSet);
System.out.println("Dog가 있는가? " + hashSet.contains("Dog"));
hashSet.remove("Cat");
System.out.println("Cat 삭제 후: " + hashSet);
System.out.println("-----------------------\n");
System.out.println("--- HashMap 예제 ---");
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("Grape", 30);
hashMap.put("Honey", 40);
System.out.println("HashMap: " + hashMap);
System.out.println("Grape의 수량: " + hashMap.get("Grape"));
hashMap.remove("Honey");
System.out.println("Honey 삭제 후: " + hashMap);
System.out.println("-----------------------\n");
}
}
17일차에는 전날 학습한 개요를 바탕으로 컬렉션 프레임워크의 ‘주요 인터페이스’들을 상세히 살펴보았습니다. 데이터를 어떤 방식으로 저장하고 관리할지에 따라 List
, Set
, Map
이라는 핵심 인터페이스로 나뉘며, 각 인터페이스가 가지는 특징과 용도를 명확히 구분하는 데 집중했습니다. List
는 순서가 있고 중복을 허용하며, Set
은 순서 없이 고유한 요소만 저장하고, Map
은 키-값 쌍으로 데이터를 관리한다는 것을 이해했습니다. 각 인터페이스의 특성을 파악하며 실제 프로그래밍에서 데이터를 다룰 때 어떤 인터페이스를 선택해야 할지 판단하는 기준을 세웠습니다.
18일차 : 입출력 스트림
package ch11;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.BufferedWriter;
public class Day18OriginalIOExamples {
public static void main(String[] args) {
System.out.println("--- FileInputStream 예제---");
FileInputStream();
System.out.println("\n--- FileReader 예제 ---");
FileReader();
System.out.println("\n--- FileOutputStream 예제 ---");
FileOutputStream();
System.out.println("\n--- FileWriter 예제 ---");
FileWriter();
}
public static void FileInputStream() {
try (FileInputStream fis = new FileInputStream("C:/Workspace/input.txt")) {
int data;
while ((data = fis.read()) != -1) {
System.out.print((char)data);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println();
}
public static void FileReader() {
try (BufferedReader br = new BufferedReader(new FileReader("C:/Workspace/input.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void FileOutputStream() {
String data = "Hello, World!";
FileOutputStream fos = null;
try {
fos = new FileOutputStream("C:/Workspace/output.txt");
fos.write(data.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void FileWriter() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("C:/Workspace/output.txt", true))) {
writer.newLine();
writer.write("Hello, Java!");
writer.newLine();
writer.write("This is another line");
} catch (IOException e) {
e.printStackTrace();
}
}
}
18일차에는 자바의 입출력(I/O) 스트림에 대해 학습하며, 데이터를 읽고 쓰는 기본적인 방법을 익혔습니다. 입출력 스트림은 프로그램과 외부 데이터 소스(파일, 네트워크 등) 간에 데이터를 주고받는 통로 역할을 합니다. 데이터를 바이트 단위로 처리하는 바이트 스트림과 문자 단위로 처리하는 문자 스트림의 두 가지 주요 종류를 이해했으며, 특히 파일을 대상으로 데이터를 읽고 쓰는 방법을 실습했습니다. FileInputStream
과 FileOutputStream
을 사용하여 바이트 단위로 파일을 다루고, FileReader
와 FileWriter
(버퍼링을 위한 BufferedReader
, BufferedWriter
와 함께)를 사용하여 문자 단위로 파일을 다루는 기초를 다졌습니다.
19일차 : 입출력 스트림
package ch11;
import java.util.Scanner;
public class StdInputStreamExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("이름을 입력하세요. --> ");
String name = scanner.nextLine(); // 사용자 입력을 문자열로 읽어들임
System.out.println("안녕, " + name + "!");
System.out.println("Hello, Java!");
int a = 10;
int b = 20;
System.out.printf("%d과 %d의 합: %d%n", a, b, a + b); // 서식을 지정해 출력
try {
int reuslt = 10 / 0; // 오류 발생
} catch (ArithmeticException e) {
System.err.println("Error: Division by zero!");
}
System.out.println("프로그램 실행 중");
}
}
19일차에는 자바에서 기본으로 제공하는 ‘표준 입출력 스트림’을 배웠습니다. 키보드 입력을 받는 System.in
, 일반 출력을 위한 System.out
, 그리고 오류 메시지를 출력하는 System.err
스트림의 사용법을 익혔습니다. 특히 Scanner
로 사용자 입력을 처리하고, System.out.println
또는 printf
로 결과를 출력하는 기본적인 방법을 실습했습니다. 이 표준 스트림들은 자바 콘솔 프로그램의 가장 기초적인 입출력 도구입니다.
20일차 : 람다 표현식
import java.util.function.Predicate;
import java.util.function.Function;
interface Check {
abstract boolean isEven(int n);
}
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable running");
}
}
public class Day20ConsolidatedSimplifiedOriginal {
public static void main(String[] args) {
Check even = n -> n % 2 == 0 ? true : false;
System.out.println("isEven(15) 결과: " + even.isEven(15));
Predicate<Integer> isEvenPredicate = (n) -> n % 2 == 0;
System.out.println("isEven.test(1) 결과: " + isEvenPredicate.test(1));
System.out.println("isEven.test(2) 결과: " + isEvenPredicate.test(2));
Function<String, String> upperCase = (str) -> str.toUpperCase();
System.out.println("upperCase.apply(\"Hello world\") 결과: " + upperCase.apply("Hello world"));
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---------------------------------");
}
}
4주차의 마지막 날, 자바 8부터 도입된 ‘람다 표현식’과 이를 활용하기 위한 ‘함수형 인터페이스’에 대해 학습했습니다. 람다 표현식은 익명 함수를 간결하게 표현할 수 있는 기능으로, 코드를 훨씬 짧고 가독성 있게 만들어 줍니다. 하나의 추상 메서드만을 가지는 인터페이스를 ‘함수형 인터페이스’라고 하며, 람다 표현식은 바로 이 함수형 인터페이스의 추상 메서드를 구현하는 데 사용됩니다.
학습 과정에서 직접 함수형 인터페이스를 정의하고 람다로 구현하는 예제를 통해 람다의 기본 문법과 활용 방법을 익혔습니다. 더 나아가, 자바 API에서 기본적으로 제공하는 유용한 함수형 인터페이스인 Predicate
(조건식 표현), Function
(입력을 받아 출력을 반환), 그리고 Runnable
(실행할 코드 블록 지정) 등을 살펴보며 람다 표현식이 실제 코드에서 어떻게 활용될 수 있는지 다양한 예시를 통해 이해했습니다. 람다 표현식은 컬렉션 프레임워크와 함께 사용될 때 그 진가를 발휘하며, 코드를 함수형 스타일로 작성하는 데 중요한 역할을 합니다.
4주차 마무리
4주차 학습을 통해 자바에서 데이터를 효과적으로 관리하는 컬렉션 프레임워크, 외부와 데이터를 주고받는 입출력 스트림, 그리고 코드를 간결하게 만드는 람다 표현식 등 필수적인 개념들을 익혔습니다. 컬렉션을 통해 다양한 데이터 구조(List, Set, Map)를 활용하는 능력을 키웠고, 입출력 스트림 학습을 통해 파일과 같은 외부 자원과 상호작용하는 기본적인 방법을 배웠습니다. 특히 람다 표현식 학습은 자바 코드를 더욱 현대적이고 효율적인 스타일로 작성하는 시야를 열어주었습니다. 이로써 더욱 다양한 애플리케이션을 개발할 수 있는 기반을 마련했습니다. 4주간의 자바 입문 과정을 성공적으로 마무리하며, 앞으로 더 심화된 내용을 학습할 발판을 마련하게 되었습니다.